<?php
class Pref_Feeds extends Handler_Protected {
+ public static $feed_languages = array("English", "Danish", "Dutch", "Finnish", "French", "German", "Hungarian", "Italian", "Norwegian",
+ "Portuguese", "Russian", "Spanish", "Swedish", "Turkish", "Simple");
function csrf_ignore($method) {
$csrf_ignored = array("index", "getfeedtree", "add", "editcats", "editfeed",
else
$search = "";
- if ($search) $search_qpart = " AND LOWER(title) LIKE LOWER('%$search%')";
+ if ($search) $search_qpart = " AND (LOWER(title) LIKE LOWER('%$search%') OR LOWER(feed_url) LIKE LOWER('%$search%'))";
// first one is set by API
$show_empty_cats = $_REQUEST['force_show_empty'] ||
- ($_REQUEST['mode'] != 2 && !$search &&
- get_pref('_PREFS_SHOW_EMPTY_CATS'));
+ ($_REQUEST['mode'] != 2 && !$search);
$items = array();
$cat['type'] = 'category';
$cat['unread'] = 0;
$cat['child_unread'] = 0;
+ $cat['auxcounter'] = 0;
+ $cat['parent_id'] = $cat_id;
$cat['items'] = $this->get_category_items($line['id']);
- $cat['param'] = vsprintf(_ngettext('(%d feed)', '(%d feeds)', count($cat['items'])), count($cat['items']));
+ $num_children = $this->calculate_children_count($cat);
+ $cat['param'] = vsprintf(_ngettext('(%d feed)', '(%d feeds)', (int) $num_children), $num_children);
- if (count($cat['items']) > 0 || $show_empty_cats)
+ if ($num_children > 0 || $show_empty_cats)
array_push($items, $cat);
}
$feed = array();
$feed['id'] = 'FEED:' . $feed_line['id'];
$feed['bare_id'] = (int)$feed_line['id'];
+ $feed['auxcounter'] = 0;
$feed['name'] = $feed_line['title'];
$feed['checkbox'] = false;
$feed['unread'] = 0;
/* Plugin feeds for -1 */
- global $pluginhost;
-
- $feeds = $pluginhost->get_feeds(-1);
+ $feeds = PluginHost::getInstance()->get_feeds(-1);
if ($feeds) {
foreach ($feeds as $feed) {
$item = array();
$item['id'] = 'FEED:' . $feed_id;
$item['bare_id'] = (int)$feed_id;
+ $item['auxcounter'] = 0;
$item['name'] = $feed['title'];
$item['checkbox'] = false;
$item['error'] = '';
if ($enable_cats) {
$show_empty_cats = $_REQUEST['force_show_empty'] ||
- ($_REQUEST['mode'] != 2 && !$search &&
- get_pref('_PREFS_SHOW_EMPTY_CATS'));
+ ($_REQUEST['mode'] != 2 && !$search);
$result = $this->dbh->query("SELECT id, title FROM ttrss_feed_categories
WHERE owner_uid = " . $_SESSION["uid"] . " AND parent_cat IS NULL ORDER BY order_id, title");
$cat = array();
$cat['id'] = 'CAT:' . $line['id'];
$cat['bare_id'] = (int)$line['id'];
+ $cat['auxcounter'] = 0;
$cat['name'] = $line['title'];
$cat['items'] = array();
$cat['checkbox'] = false;
$cat['items'] = $this->get_category_items($line['id']);
- $cat['param'] = vsprintf(_ngettext('(%d feed)', '(%d feeds)', count($cat['items'])), count($cat['items']));
+ $num_children = $this->calculate_children_count($cat);
+ $cat['param'] = vsprintf(_ngettext('(%d feed)', '(%d feeds)', (int) $num_children), $num_children);
- if (count($cat['items']) > 0 || $show_empty_cats)
+ if ($num_children > 0 || $show_empty_cats)
array_push($root['items'], $cat);
$root['param'] += count($cat['items']);
$cat = array();
$cat['id'] = 'CAT:0';
$cat['bare_id'] = 0;
+ $cat['auxcounter'] = 0;
$cat['name'] = __("Uncategorized");
$cat['items'] = array();
$cat['type'] = 'category';
$feed = array();
$feed['id'] = 'FEED:' . $feed_line['id'];
$feed['bare_id'] = (int)$feed_line['id'];
+ $feed['auxcounter'] = 0;
$feed['name'] = $feed_line['title'];
$feed['checkbox'] = false;
$feed['error'] = $feed_line['last_error'];
if (count($cat['items']) > 0 || $show_empty_cats)
array_push($root['items'], $cat);
- $root['param'] += count($cat['items']);
- $root['param'] = vsprintf(_ngettext('(%d feed)', '(%d feeds)', count($cat['items'])), count($cat['items']));
+ $num_children = $this->calculate_children_count($root);
+ $root['param'] = vsprintf(_ngettext('(%d feed)', '(%d feeds)', (int) $num_children), $num_children);
} else {
$feed_result = $this->dbh->query("SELECT id, title, last_error,
$feed = array();
$feed['id'] = 'FEED:' . $feed_line['id'];
$feed['bare_id'] = (int)$feed_line['id'];
+ $feed['auxcounter'] = 0;
$feed['name'] = $feed_line['title'];
$feed['checkbox'] = false;
$feed['error'] = $feed_line['last_error'];
if ($_REQUEST['mode'] != 2) {
$fl['items'] = array($root);
} else {
- $fl['items'] =& $root['items'];
+ $fl['items'] = $root['items'];
}
return $fl;
return;
}
- function togglehiddenfeedcats() {
- set_pref('_PREFS_SHOW_EMPTY_CATS',
- (get_pref('_PREFS_SHOW_EMPTY_CATS') ? 'false' : 'true'));
- }
-
private function process_category_order(&$data_map, $item_id, $parent_id = false, $nest_level = 0) {
$debug = isset($_REQUEST["debug"]);
if ($debug) _debug("$prefix C: $item_id P: $parent_id");
- $bare_item_id = substr($item_id, strpos($item_id, ':')+1);
+ $bare_item_id = $this->dbh->escape_string(substr($item_id, strpos($item_id, ':')+1));
if ($item_id != 'root') {
if ($parent_id && $parent_id != 'root') {
if ($cat && is_array($cat)) {
foreach ($cat as $item) {
$id = $item['_reference'];
- $bare_id = substr($id, strpos($id, ':')+1);
+ $bare_id = $this->dbh->escape_string(substr($id, strpos($id, ':')+1));
if ($debug) _debug("$prefix [$order_id] $id/$bare_id");
# print_r($data['items']);
if (is_array($data) && is_array($data['items'])) {
- $cat_order_id = 0;
+# $cat_order_id = 0;
$data_map = array();
$root_item = false;
if (isset($item['items']['_reference'])) {
$data_map[$item['id']] = array($item['items']);
} else {
- $data_map[$item['id']] =& $item['items'];
+ $data_map[$item['id']] = $item['items'];
}
}
if ($item['id'] == 'root') {
$feed_id = $this->dbh->escape_string($_REQUEST["feed_id"]);
if (is_file($icon_file) && $feed_id) {
- if (filesize($icon_file) < 20000) {
+ if (filesize($icon_file) < 65535) {
$result = $this->dbh->query("SELECT id FROM ttrss_feeds
WHERE id = '$feed_id' AND owner_uid = ". $_SESSION["uid"]);
if ($this->dbh->num_rows($result) != 0) {
@unlink(ICONS_DIR . "/$feed_id.ico");
if (rename($icon_file, ICONS_DIR . "/$feed_id.ico")) {
-
- require_once "colors.php";
-
- $favicon_color = $this->dbh->escape_string(
- calculate_avg_color(ICONS_DIR . "/$feed_id.ico"));
-
$this->dbh->query("UPDATE ttrss_feeds SET
- favicon_avg_color = '$favicon_color'
+ favicon_avg_color = ''
WHERE id = '$feed_id'");
$rc = 0;
global $purge_intervals;
global $update_intervals;
+ print '<div dojoType="dijit.layout.TabContainer" style="height : 450px">
+ <div dojoType="dijit.layout.ContentPane" title="'.__('General').'">';
+
$feed_id = $this->dbh->escape_string($_REQUEST["id"]);
$result = $this->dbh->query(
$title = htmlspecialchars($this->dbh->fetch_result($result,
0, "title"));
- print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"id\" value=\"$feed_id\">";
- print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pref-feeds\">";
- print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"editSave\">";
+ print_hidden("id", "$feed_id");
+ print_hidden("op", "pref-feeds");
+ print_hidden("method", "editSave");
print "<div class=\"dlgSec\">".__("Feed")."</div>";
print "<div class=\"dlgSecCont\">";
$last_error = $this->dbh->fetch_result($result, 0, "last_error");
if ($last_error) {
- print " <span title=\"".htmlspecialchars($last_error)."\"
- class=\"feed_error\">(error)</span>";
+ print " <img src=\"images/error.png\" alt=\"(error)\"
+ style=\"vertical-align : middle\"
+ title=\"".htmlspecialchars($last_error)."\">";
}
'dojoType="dijit.form.Select"');
}
+ /* FTS Stemming Language */
+
+ if (DB_TYPE == "pgsql") {
+ $feed_language = $this->dbh->fetch_result($result, 0, "feed_language");
+
+ print "<hr/>";
+
+ print __('Language:') . " ";
+ print_select("feed_language", $feed_language, $this::$feed_languages,
+ 'dojoType="dijit.form.Select"');
+ }
+
print "</div>";
print "<div class=\"dlgSec\">".__("Update")."</div>";
print "<input dojoType=\"dijit.form.TextBox\" id=\"feedEditDlg_login\"
placeHolder=\"".__("Login")."\"
+ autocomplete=\"new-password\"
name=\"auth_login\" value=\"$auth_login\"><hr/>";
$auth_pass = $this->dbh->fetch_result($result, 0, "auth_pass");
- if ($auth_pass_encrypted) {
+ if ($auth_pass_encrypted && function_exists("mcrypt_decrypt")) {
require_once "crypt.php";
$auth_pass = decrypt_string($auth_pass);
}
$auth_pass = htmlspecialchars($auth_pass);
print "<input dojoType=\"dijit.form.TextBox\" type=\"password\" name=\"auth_pass\"
+ autocomplete=\"new-password\"
placeHolder=\"".__("Password")."\"
value=\"$auth_pass\">";
</div>";
print "</div>";
- print "<div class=\"dlgSec\">".__("Options")."</div>";
- print "<div class=\"dlgSecCont\">";
+
+ print '</div><div dojoType="dijit.layout.ContentPane" title="'.__('Options').'">';
+
+ //print "<div class=\"dlgSec\">".__("Options")."</div>";
+ print "<div class=\"dlgSecSimple\">";
$private = sql_bool_to_bool($this->dbh->fetch_result($result, 0, "private"));
print "</div>";
+ print '</div><div dojoType="dijit.layout.ContentPane" title="'.__('Icon').'">';
+
/* Icon */
- print "<div class=\"dlgSec\">".__("Icon")."</div>";
- print "<div class=\"dlgSecCont\">";
+ print "<div class=\"dlgSecSimple\">";
print "<iframe name=\"icon_upload_iframe\"
style=\"width: 400px; height: 100px; display: none;\"></iframe>";
<input id=\"icon_file\" size=\"10\" name=\"icon_file\" type=\"file\">
<input type=\"hidden\" name=\"op\" value=\"pref-feeds\">
<input type=\"hidden\" name=\"feed_id\" value=\"$feed_id\">
- <input type=\"hidden\" name=\"method\" value=\"uploadicon\">
- <button dojoType=\"dijit.form.Button\" onclick=\"return uploadFeedIcon();\"
+ <input type=\"hidden\" name=\"method\" value=\"uploadicon\"><p>
+ <button class=\"\" dojoType=\"dijit.form.Button\" onclick=\"return uploadFeedIcon();\"
type=\"submit\">".__('Replace')."</button>
- <button dojoType=\"dijit.form.Button\" onclick=\"return removeFeedIcon($feed_id);\"
+ <button class=\"\" dojoType=\"dijit.form.Button\" onclick=\"return removeFeedIcon($feed_id);\"
type=\"submit\">".__('Remove')."</button>
</form>";
print "</div>";
+ print '</div><div dojoType="dijit.layout.ContentPane" title="'.__('Plugins').'">';
+
+ PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_EDIT_FEED,
+ "hook_prefs_edit_feed", $feed_id);
+
+
+ print "</div></div>";
+
$title = htmlspecialchars($title, ENT_QUOTES);
print "<div class='dlgButtons'>
<div style=\"float : left\">
- <button dojoType=\"dijit.form.Button\" onclick='return unsubscribeFeed($feed_id, \"$title\")'>".
+ <button class=\"danger\" dojoType=\"dijit.form.Button\" onclick='return unsubscribeFeed($feed_id, \"$title\")'>".
__('Unsubscribe')."</button>";
if (PUBSUBHUBBUB_ENABLED) {
<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('feedEditDlg').hide()\">".__('Cancel')."</button>
</div>";
+
return;
}
print "<p>";
- print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"ids\" value=\"$feed_ids\">";
- print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pref-feeds\">";
- print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"batchEditSave\">";
+ print_hidden("ids", "$feed_ids");
+ print_hidden("op", "pref-feeds");
+ print_hidden("method", "batchEditSave");
print "<div class=\"dlgSec\">".__("Feed")."</div>";
print "<div class=\"dlgSecCont\">";
- /* Title */
-
- print "<input dojoType=\"dijit.form.ValidationTextBox\"
- disabled=\"1\" style=\"font-size : 16px; width : 20em;\" required=\"1\"
- name=\"title\" value=\"$title\">";
-
- $this->batch_edit_cbox("title");
-
- /* Feed URL */
-
- print "<br/>";
-
- print __('URL:') . " ";
- print "<input dojoType=\"dijit.form.ValidationTextBox\" disabled=\"1\"
- required=\"1\" regExp='^(http|https)://.*' style=\"width : 20em\"
- name=\"feed_url\" value=\"$feed_url\">";
-
- $this->batch_edit_cbox("feed_url");
-
/* Category */
if (get_pref('ENABLE_FEED_CATS')) {
- print "<br/>";
-
print __('Place in category:') . " ";
- print_feed_cat_select("cat_id", $cat_id,
+ print_feed_cat_select("cat_id", false,
'disabled="1" dojoType="dijit.form.Select"');
$this->batch_edit_cbox("cat_id");
}
+ /* FTS Stemming Language */
+
+ if (DB_TYPE == "pgsql") {
+ print "<hr/>";
+
+ print __('Language:') . " ";
+ print_select("feed_language", "", $this::$feed_languages,
+ 'disabled="1" dojoType="dijit.form.Select"');
+
+ $this->batch_edit_cbox("feed_language");
+ }
+
print "</div>";
print "<div class=\"dlgSec\">".__("Update")."</div>";
/* Update Interval */
- print_select_hash("update_interval", $update_interval, $update_intervals,
+ print_select_hash("update_interval", "", $update_intervals,
'disabled="1" dojoType="dijit.form.Select"');
$this->batch_edit_cbox("update_interval");
print __('Article purging:') . " ";
- print_select_hash("purge_interval", $purge_interval, $purge_intervals,
+ print_select_hash("purge_interval", "", $purge_intervals,
'disabled="1" dojoType="dijit.form.Select"');
$this->batch_edit_cbox("purge_interval");
print "<input dojoType=\"dijit.form.TextBox\"
placeHolder=\"".__("Login")."\" disabled=\"1\"
- name=\"auth_login\" value=\"$auth_login\">";
+ autocomplete=\"new-password\"
+ name=\"auth_login\" value=\"\">";
$this->batch_edit_cbox("auth_login");
- print "<br/><input dojoType=\"dijit.form.TextBox\" type=\"password\" name=\"auth_pass\"
+ print "<hr/> <input dojoType=\"dijit.form.TextBox\" type=\"password\" name=\"auth_pass\"
+ autocomplete=\"new-password\"
placeHolder=\"".__("Password")."\" disabled=\"1\"
- value=\"$auth_pass\">";
+ value=\"\">";
$this->batch_edit_cbox("auth_pass");
$mark_unread_on_update = checkbox_to_sql_bool(
$this->dbh->escape_string($_POST["mark_unread_on_update"]));
- if (strlen(FEED_CRYPT_KEY) > 0) {
- require_once "crypt.php";
- $auth_pass = substr(encrypt_string($auth_pass), 0, 250);
- $auth_pass_encrypted = 'true';
- } else {
- $auth_pass_encrypted = 'false';
- }
+ $feed_language = $this->dbh->escape_string(trim($_POST["feed_language"]));
+ $auth_pass_encrypted = 'false';
$auth_pass = $this->dbh->escape_string($auth_pass);
if (get_pref('ENABLE_FEED_CATS')) {
if (!$batch) {
- $result = $this->dbh->query("UPDATE ttrss_feeds SET
+ $result = db_query("SELECT feed_url FROM ttrss_feeds WHERE id = " . $feed_id);
+ $orig_feed_url = db_fetch_result($result, 0, "feed_url");
+
+ $reset_basic_info = $orig_feed_url != $feed_link;
+
+ $this->dbh->query("UPDATE ttrss_feeds SET
$category_qpart
title = '$feed_title', feed_url = '$feed_link',
update_interval = '$upd_intl',
hide_images = $hide_images,
include_in_digest = $include_in_digest,
always_display_enclosures = $always_display_enclosures,
- mark_unread_on_update = $mark_unread_on_update
+ mark_unread_on_update = $mark_unread_on_update,
+ feed_language = '$feed_language'
WHERE id = '$feed_id' AND owner_uid = " . $_SESSION["uid"]);
+ if ($reset_basic_info) {
+ require_once "rssfuncs.php";
+
+ set_basic_feed_info($feed_id);
+ }
+
+ PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_SAVE_FEED,
+ "hook_prefs_save_feed", $feed_id);
+
} else {
$feed_data = array();
$qpart = $category_qpart_nocomma;
break;
+ case "feed_language":
+ $qpart = "feed_language = '$feed_language'";
+ break;
+
}
if ($qpart) {
__("Feeds with errors") . "</button>";
}
- if (DB_TYPE == "pgsql") {
- $interval_qpart = "NOW() - INTERVAL '3 months'";
- } else {
- $interval_qpart = "DATE_SUB(NOW(), INTERVAL 3 MONTH)";
- }
-
- $result = $this->dbh->query("SELECT COUNT(*) AS num_inactive FROM ttrss_feeds WHERE
- (SELECT MAX(updated) FROM ttrss_entries, ttrss_user_entries WHERE
- ttrss_entries.id = ref_id AND
- ttrss_user_entries.feed_id = ttrss_feeds.id) < $interval_qpart AND
- ttrss_feeds.owner_uid = ".$_SESSION["uid"]);
-
- $num_inactive = $this->dbh->fetch_result($result, 0, "num_inactive");
-
- if ($num_inactive > 0) {
- $inactive_button = "<button dojoType=\"dijit.form.Button\"
- onclick=\"showInactiveFeeds()\">" .
- __("Inactive feeds") . "</button>";
- }
+ $inactive_button = "<button dojoType=\"dijit.form.Button\"
+ id=\"pref_feeds_inactive_btn\"
+ style=\"display : none\"
+ onclick=\"showInactiveFeeds()\">" .
+ __("Inactive feeds") . "</button>";
$feed_search = $this->dbh->escape_string($_REQUEST["search"]);
print $error_button;
print $inactive_button;
- print "<button onclick=\"toggleHiddenFeedCats()\"
- dojoType=\"dijit.form.Button\">".__('(Un)hide empty categories')."</button>";
-
if (defined('_ENABLE_FEED_DEBUGGING')) {
print "<select id=\"feedActionChooser\" onchange=\"feedActionChange()\">
<div dojoType=\"fox.PrefFeedTree\" id=\"feedTree\"
dndController=\"dijit.tree.dndSource\"
betweenThreshold=\"5\"
+ autoExpand='true'
model=\"feedModel\" openOnClick=\"false\">
<script type=\"dojo/method\" event=\"onClick\" args=\"item\">
var id = String(item.id);
</script>
<script type=\"dojo/method\" event=\"onLoad\" args=\"item\">
Element.hide(\"feedlistLoading\");
+
+ checkInactiveFeeds();
</script>
</div>";
print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__('OPML')."\">";
- print "<p>" . __("Using OPML you can export and import your feeds, filters, labels and Tiny Tiny RSS settings.") . " ";
-
- print __("Only main settings profile can be migrated using OPML.") . "</p>";
+ print "<p>" . __("Using OPML you can export and import your feeds, filters, labels and Tiny Tiny RSS settings.") .
+ __("Only main settings profile can be migrated using OPML.") . "</p>";
print "<iframe id=\"upload_iframe\"
name=\"upload_iframe\" onload=\"opmlImportComplete(this)\"
print "<hr>";
+ $opml_export_filename = "TinyTinyRSS_".date("Y-m-d").".opml";
+
print "<p>" . __('Filename:') .
- " <input type=\"text\" id=\"filename\" value=\"TinyTinyRSS.opml\" /> " .
+ " <input type=\"text\" id=\"filename\" value=\"$opml_export_filename\" /> " .
__('Include settings') . "<input type=\"checkbox\" id=\"settings\" checked=\"1\"/>";
print "</p><button dojoType=\"dijit.form.Button\"
print "<hr>";
- print "<p>".__('Your OPML can be published publicly and can be subscribed by anyone who knows the URL below.') . " ";
+ print "<p>" . __('Your OPML can be published publicly and can be subscribed by anyone who knows the URL below.') . "</p>";
- print __("Published OPML does not include your Tiny Tiny RSS settings, feeds that require authentication or feeds hidden from Popular feeds.") . "</p>";
+ print_warning("Published OPML does not include your Tiny Tiny RSS settings, feeds that require authentication or feeds hidden from Popular feeds.");
print "<button dojoType=\"dijit.form.Button\" onclick=\"return displayDlg('".__("Public OPML URL")."','pubOPMLUrl')\">".
__('Display published OPML URL')."</button> ";
- global $pluginhost;
- $pluginhost->run_hooks($pluginhost::HOOK_PREFS_TAB_SECTION,
+ PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION,
"hook_prefs_tab_section", "prefFeedsOPML");
print "</div>"; # pane
print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__('Firefox integration')."\">";
- print "<p>" . __('This Tiny Tiny RSS site can be used as a Firefox Feed Reader by clicking the link below.') . "</p>";
+ print_notice(__('This Tiny Tiny RSS site can be used as a Firefox Feed Reader by clicking the link below.'));
print "<p>";
print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__('Published & shared articles / Generated feeds')."\">";
- print "<h3>" . __("Published articles and generated feeds") . "</h3>";
-
- print "<p>".__('Published articles are exported as a public RSS feed and can be subscribed by anyone who knows the URL specified below.')."</p>";
+ print "<p>" . __('Published articles are exported as a public RSS feed and can be subscribed by anyone who knows the URL specified below.') . "</p>";
$rss_url = '-2::' . htmlspecialchars(get_self_url_prefix() .
"/public.php?op=rss&id=-2&view-mode=all_articles");;
+ print "<p>";
+
print "<button dojoType=\"dijit.form.Button\" onclick=\"return displayDlg('".__("View as RSS")."','generatedFeed', '$rss_url')\">".
__('Display URL')."</button> ";
- print "<button dojoType=\"dijit.form.Button\" onclick=\"return clearFeedAccessKeys()\">".
+ print "<button class=\"warning\" dojoType=\"dijit.form.Button\" onclick=\"return clearFeedAccessKeys()\">".
__('Clear all generated URLs')."</button> ";
- print "<h3>" . __("Articles shared by URL") . "</h3>";
-
- print "<p>" . __("You can disable all articles shared by unique URLs here.") . "</p>";
+ print "</p>";
- print "<button dojoType=\"dijit.form.Button\" onclick=\"return clearArticleAccessKeys()\">".
- __('Unshare all articles')."</button> ";
-
- global $pluginhost;
- $pluginhost->run_hooks($pluginhost::HOOK_PREFS_TAB_SECTION,
+ PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION,
"hook_prefs_tab_section", "prefFeedsPublishedGenerated");
print "</div>"; #pane
- global $pluginhost;
-
- $pluginhost->run_hooks($pluginhost::HOOK_PREFS_TAB,
+ PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB,
"hook_prefs_tab", "prefFeeds");
print "</div>"; #container
$obj['updated'] = $updated;
$obj['icon'] = getFeedIcon($feed_id);
$obj['bare_id'] = $feed_id;
+ $obj['auxcounter'] = 0;
return $obj;
}
GROUP BY ttrss_feeds.title, ttrss_feeds.id, ttrss_feeds.site_url, ttrss_feeds.feed_url
ORDER BY last_article");
- print "<h2" .__("These feeds have not been updated with new content for 3 months (oldest first):") . "</h2>";
+ print "<p" .__("These feeds have not been updated with new content for 3 months (oldest first):") . "</p>";
print "<div dojoType=\"dijit.Toolbar\">";
print "<div dojoType=\"dijit.form.DropDownButton\">".
while ($line = $this->dbh->fetch_assoc($result)) {
- $class = ($lnum % 2) ? "even" : "odd";
$feed_id = $line["id"];
$this_row_id = "id=\"FUPDD-$feed_id\"";
# class needed for selectTableRows()
print "<tr class=\"placeholder\" $this_row_id>";
- $edit_title = htmlspecialchars($line["title"]);
-
# id needed for selectTableRows()
print "<td width='5%' align='center'><input
onclick='toggleSelectRow2(this);' dojoType=\"dijit.form.CheckBox\"
print "<div class='dlgButtons'>";
print "<div style='float : left'>";
- print "<button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('inactiveFeedsDlg').removeSelected()\">"
+ print "<button class=\"danger\" dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('inactiveFeedsDlg').removeSelected()\">"
.__('Unsubscribe from selected feeds')."</button> ";
print "</div>";
}
function feedsWithErrors() {
- print "<h2>" . __("These feeds have not been updated because of errors:") .
- "</h2>";
-
$result = $this->dbh->query("SELECT id,title,feed_url,last_error,site_url
FROM ttrss_feeds WHERE last_error != '' AND owner_uid = ".$_SESSION["uid"]);
while ($line = $this->dbh->fetch_assoc($result)) {
- $class = ($lnum % 2) ? "even" : "odd";
$feed_id = $line["id"];
$this_row_id = "id=\"FERDD-$feed_id\"";
# class needed for selectTableRows()
print "<tr class=\"placeholder\" $this_row_id>";
- $edit_title = htmlspecialchars($line["title"]);
-
# id needed for selectTableRows()
print "<td width='5%' align='center'><input
onclick='toggleSelectRow2(this);' dojoType=\"dijit.form.CheckBox\"
print "<div class='dlgButtons'>";
print "<div style='float : left'>";
- print "<button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('errorFeedsDlg').removeSelected()\">"
+ print "<button class=\"danger\" dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('errorFeedsDlg').removeSelected()\">"
.__('Unsubscribe from selected feeds')."</button> ";
print "</div>";
}
function batchSubscribe() {
- print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pref-feeds\">";
- print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"batchaddfeeds\">";
+ print_hidden("op", "pref-feeds");
+ print_hidden("method", "batchaddfeeds");
print "<table width='100%'><tr><td>
".__("Add one valid RSS feed per line (no feed detection is done)")."
}
print "</td></tr><tr><td colspan='2'>";
print "<textarea
- style='font-size : 12px; width : 100%; height: 200px;'
+ style='font-size : 12px; width : 98%; height: 200px;'
placeHolder=\"".__("Feeds to subscribe, One per line")."\"
dojoType=\"dijit.form.SimpleTextarea\" required=\"1\" name=\"feeds\"></textarea>";
" <input
placeHolder=\"".__("Password")."\"
dojoType=\"dijit.form.TextBox\" type='password'
+ autocomplete=\"new-password\"
style=\"width : 10em;\" name='pass'\">".
"</div>";
"SELECT id FROM ttrss_feeds
WHERE feed_url = '$feed' AND owner_uid = ".$_SESSION["uid"]);
- if (strlen(FEED_CRYPT_KEY) > 0) {
- require_once "crypt.php";
- $pass = substr(encrypt_string($pass), 0, 250);
- $auth_pass_encrypted = 'true';
- } else {
- $auth_pass_encrypted = 'false';
- }
-
+ $auth_pass_encrypted = 'false';
$pass = $this->dbh->escape_string($pass);
if ($this->dbh->num_rows($result) == 0) {
AND owner_uid = " . $owner_uid);
if ($this->dbh->num_rows($result) == 1) {
- $key = $this->dbh->escape_string(sha1(uniqid(rand(), true)));
+ $key = $this->dbh->escape_string(uniqid_short());
$this->dbh->query("UPDATE ttrss_access_keys SET access_key = '$key'
WHERE feed_id = '$feed_id' AND is_cat = $sql_is_cat
owner_uid = " . $_SESSION["uid"]);
}
+ private function calculate_children_count($cat) {
+ $c = 0;
+
+ foreach ($cat['items'] as $child) {
+ if ($child['type'] == 'category') {
+ $c += $this->calculate_children_count($child);
+ } else {
+ $c += 1;
+ }
+ }
+ return $c;
+ }
+
+ function getinactivefeeds() {
+ if (DB_TYPE == "pgsql") {
+ $interval_qpart = "NOW() - INTERVAL '3 months'";
+ } else {
+ $interval_qpart = "DATE_SUB(NOW(), INTERVAL 3 MONTH)";
+ }
+
+ $result = $this->dbh->query("SELECT COUNT(*) AS num_inactive FROM ttrss_feeds WHERE
+ (SELECT MAX(updated) FROM ttrss_entries, ttrss_user_entries WHERE
+ ttrss_entries.id = ref_id AND
+ ttrss_user_entries.feed_id = ttrss_feeds.id) < $interval_qpart AND
+ ttrss_feeds.owner_uid = ".$_SESSION["uid"]);
+
+ print (int) $this->dbh->fetch_result($result, 0, "num_inactive");
+ }
}
?>