From 257efb43c6e32226280d8198acc946a2fc4c454f Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Mon, 15 Feb 2021 15:52:28 +0300 Subject: article: unify naming --- classes/pluginhost.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'classes/pluginhost.php') diff --git a/classes/pluginhost.php b/classes/pluginhost.php index 42f7f6bf9..6f223ee11 100755 --- a/classes/pluginhost.php +++ b/classes/pluginhost.php @@ -47,7 +47,7 @@ class PluginHost { const HOOK_QUERY_HEADLINES = "hook_query_headlines"; // hook_query_headlines($row) (byref) const HOOK_HOUSE_KEEPING = "hook_house_keeping"; //*1 // GLOBAL: hook_house_keeping() const HOOK_SEARCH = "hook_search"; // hook_search($query) - const HOOK_FORMAT_ENCLOSURES = "hook_format_enclosures"; // hook_format_enclosures($rv, $result, $id, $always_display_enclosures, $article_content, $hide_images) (byref) + const HOOK_FORMAT_ENCLOSURES = "hook_format_enclosures"; // hook__format_enclosures($rv, $result, $id, $always_display_enclosures, $article_content, $hide_images) (byref) const HOOK_SUBSCRIBE_FEED = "hook_subscribe_feed"; // hook_subscribe_feed($contents, $url, $auth_login, $auth_pass) (byref) const HOOK_HEADLINES_BEFORE = "hook_headlines_before"; // hook_headlines_before($feed, $is_cat, $qfh_ret) const HOOK_RENDER_ENCLOSURE = "hook_render_enclosure"; // hook_render_enclosure($entry, $hide_images) -- cgit v1.2.3-54-g00ecf From 273ada7353b185e20452d54a8206d5e0cef9e573 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Wed, 17 Feb 2021 09:59:14 +0300 Subject: * implement shortcut syntax for exposed plugin methods * move shared article rendering code to share plugin --- classes/handler/public.php | 162 ------------------------------------------- classes/pluginhost.php | 5 +- plugins/share/init.php | 169 ++++++++++++++++++++++++++++++++++++++++++++- public.php | 11 +++ 4 files changed, 180 insertions(+), 167 deletions(-) (limited to 'classes/pluginhost.php') diff --git a/classes/handler/public.php b/classes/handler/public.php index b0bed5d1c..b810019c1 100755 --- a/classes/handler/public.php +++ b/classes/handler/public.php @@ -294,168 +294,6 @@ class Handler_Public extends Handler { } } - function share() { - $uuid = clean($_REQUEST["key"]); - - if ($uuid) { - $sth = $this->pdo->prepare("SELECT ref_id, owner_uid - FROM ttrss_user_entries WHERE uuid = ?"); - $sth->execute([$uuid]); - - if ($row = $sth->fetch()) { - header("Content-Type: text/html"); - - $id = $row["ref_id"]; - $owner_uid = $row["owner_uid"]; - - print $this->format_article($id, $owner_uid); - - return; - } - } - - header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found"); - print "Article not found."; - } - - private function format_article($id, $owner_uid) { - - $pdo = Db::pdo(); - - $sth = $pdo->prepare("SELECT id,title,link,content,feed_id,comments,int_id,lang, - ".SUBSTRING_FOR_DATE."(updated,1,16) as updated, - (SELECT site_url FROM ttrss_feeds WHERE id = feed_id) as site_url, - (SELECT title FROM ttrss_feeds WHERE id = feed_id) as feed_title, - (SELECT hide_images FROM ttrss_feeds WHERE id = feed_id) as hide_images, - (SELECT always_display_enclosures FROM ttrss_feeds WHERE id = feed_id) as always_display_enclosures, - num_comments, - tag_cache, - author, - guid, - note - FROM ttrss_entries,ttrss_user_entries - WHERE id = ? AND ref_id = id AND owner_uid = ?"); - $sth->execute([$id, $owner_uid]); - - $rv = ''; - - if ($line = $sth->fetch()) { - - $line["tags"] = Article::_get_tags($id, $owner_uid, $line["tag_cache"]); - unset($line["tag_cache"]); - - $line["content"] = Sanitizer::sanitize($line["content"], - $line['hide_images'], - $owner_uid, $line["site_url"], false, $line["id"]); - - PluginHost::getInstance()->chain_hooks_callback(PluginHost::HOOK_RENDER_ARTICLE, - function ($result) use (&$line) { - $line = $result; - }, - $line); - - $line['content'] = DiskCache::rewrite_urls($line['content']); - - header("Content-Type: text/html"); - - $rv .= " - - - ".$line["title"]."". - javascript_tag("lib/prototype.js"). - javascript_tag("js/utility.js")." - - - "; - - $rv .= "\n"; - $rv .= "\n"; - - $rv .= ""; - - $enclosures = Article::_get_enclosures($line["id"]); - list ($og_image, $og_stream) = Article::_get_image($enclosures, $line['content'], $line["site_url"]); - - if ($og_image) { - $rv .= ""; - } - - $rv .= ""; - $rv .= "
"; - - if ($line["link"]) { - $rv .= "

" . $line["title"] . "

"; - } else { - $rv .= "

" . $line["title"] . "

"; - } - - $rv .= "
"; - - /* header */ - - $rv .= "
"; - $rv .= "
"; # row - - //$entry_author = $line["author"] ? " - " . $line["author"] : ""; - $parsed_updated = TimeHelper::make_local_datetime($line["updated"], true, - $owner_uid, true); - - $rv .= "
".$line['author']."
"; - $rv .= "
$parsed_updated
"; - - $rv .= "
"; # row - - $rv .= "
"; # header - - /* content */ - - $lang = $line['lang'] ? $line['lang'] : "en"; - $rv .= "
"; - - /* content body */ - - $rv .= $line["content"]; - - /* $rv .= Article::format_article_enclosures($id, - $line["always_display_enclosures"], - $line["content"], - $line["hide_images"]); */ - - $rv .= "
"; # content - - $rv .= "
"; # post - - } - - PluginHost::getInstance()->chain_hooks_callback(PluginHost::HOOK_FORMAT_ARTICLE, - function ($result) use (&$rv) { - $rv = $result; - }, - $rv, $line); - - return $rv; - - } - function rss() { $feed = clean($_REQUEST["id"]); $key = clean($_REQUEST["key"]); diff --git a/classes/pluginhost.php b/classes/pluginhost.php index 6f223ee11..097bf987c 100755 --- a/classes/pluginhost.php +++ b/classes/pluginhost.php @@ -18,6 +18,7 @@ class PluginHost { private static $instance; const API_VERSION = 2; + const PUBLIC_METHOD_DELIMITER = "--"; // Hooks marked with *1 are run in global context and available // to plugins loaded in config.php only @@ -617,9 +618,7 @@ class PluginHost { http_build_query( array_merge( [ - "op" => "pluginhandler", - "plugin" => strtolower(get_class($sender)), - "pmethod" => $method + "op" => strtolower(get_class($sender) . PluginHost::PUBLIC_METHOD_DELIMITER . $method), ], $params)); } else { diff --git a/plugins/share/init.php b/plugins/share/init.php index a569393fe..6b7b81a2d 100644 --- a/plugins/share/init.php +++ b/plugins/share/init.php @@ -16,6 +16,10 @@ class Share extends Plugin { $host->add_hook($host::HOOK_PREFS_TAB_SECTION, $this); } + function is_public_method($method) { + return $method == "get"; + } + function get_js() { return file_get_contents(__DIR__ . "/share.js"); } @@ -78,6 +82,168 @@ class Share extends Plugin { title='".__('Share by URL')."'>link"; } + function get() { + $uuid = clean($_REQUEST["key"] ?? ""); + + if ($uuid) { + $sth = $this->pdo->prepare("SELECT ref_id, owner_uid + FROM ttrss_user_entries WHERE uuid = ?"); + $sth->execute([$uuid]); + + if ($row = $sth->fetch()) { + header("Content-Type: text/html"); + + $id = $row["ref_id"]; + $owner_uid = $row["owner_uid"]; + + print $this->format_article($id, $owner_uid); + + return; + } + } + + header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found"); + print "Article not found."; + } + + private function format_article($id, $owner_uid) { + + $pdo = Db::pdo(); + + $sth = $pdo->prepare("SELECT id,title,link,content,feed_id,comments,int_id,lang, + ".SUBSTRING_FOR_DATE."(updated,1,16) as updated, + (SELECT site_url FROM ttrss_feeds WHERE id = feed_id) as site_url, + (SELECT title FROM ttrss_feeds WHERE id = feed_id) as feed_title, + (SELECT hide_images FROM ttrss_feeds WHERE id = feed_id) as hide_images, + (SELECT always_display_enclosures FROM ttrss_feeds WHERE id = feed_id) as always_display_enclosures, + num_comments, + tag_cache, + author, + guid, + note + FROM ttrss_entries,ttrss_user_entries + WHERE id = ? AND ref_id = id AND owner_uid = ?"); + $sth->execute([$id, $owner_uid]); + + $rv = ''; + + if ($line = $sth->fetch()) { + + $line["tags"] = Article::_get_tags($id, $owner_uid, $line["tag_cache"]); + unset($line["tag_cache"]); + + $line["content"] = Sanitizer::sanitize($line["content"], + $line['hide_images'], + $owner_uid, $line["site_url"], false, $line["id"]); + + PluginHost::getInstance()->chain_hooks_callback(PluginHost::HOOK_RENDER_ARTICLE, + function ($result) use (&$line) { + $line = $result; + }, + $line); + + $line['content'] = DiskCache::rewrite_urls($line['content']); + + header("Content-Type: text/html"); + + $rv .= " + + + ".$line["title"]."". + javascript_tag("lib/prototype.js"). + javascript_tag("js/utility.js")." + + + "; + + $rv .= "\n"; + $rv .= "\n"; + + $rv .= ""; + + $enclosures = Article::_get_enclosures($line["id"]); + list ($og_image, $og_stream) = Article::_get_image($enclosures, $line['content'], $line["site_url"]); + + if ($og_image) { + $rv .= ""; + } + + $rv .= ""; + $rv .= "
"; + + if ($line["link"]) { + $rv .= "

" . $line["title"] . "

"; + } else { + $rv .= "

" . $line["title"] . "

"; + } + + $rv .= "
"; + + /* header */ + + $rv .= "
"; + $rv .= "
"; # row + + //$entry_author = $line["author"] ? " - " . $line["author"] : ""; + $parsed_updated = TimeHelper::make_local_datetime($line["updated"], true, + $owner_uid, true); + + $rv .= "
".$line['author']."
"; + $rv .= "
$parsed_updated
"; + + $rv .= "
"; # row + + $rv .= "
"; # header + + /* content */ + + $lang = $line['lang'] ? $line['lang'] : "en"; + $rv .= "
"; + + /* content body */ + + $rv .= $line["content"]; + + /* $rv .= Article::format_article_enclosures($id, + $line["always_display_enclosures"], + $line["content"], + $line["hide_images"]); */ + + $rv .= "
"; # content + + $rv .= "
"; # post + + } + + PluginHost::getInstance()->chain_hooks_callback(PluginHost::HOOK_FORMAT_ARTICLE, + function ($result) use (&$rv) { + $rv = $result; + }, + $rv, $line); + + return $rv; + + } + function shareDialog() { $id = (int)clean($_REQUEST['id'] ?? 0); @@ -96,8 +262,7 @@ class Share extends Plugin { $sth->execute([$uuid, $id, $_SESSION['uid']]); } - $url_path = get_self_url_prefix() . "/public.php?op=share&key=$uuid"; - + $url_path = $this->host->get_public_method_url($this, "get", ["key" => $uuid]); ?>
diff --git a/public.php b/public.php index 59b5a499c..fadb2f14d 100644 --- a/public.php +++ b/public.php @@ -17,6 +17,17 @@ $method = (string)clean($_REQUEST["op"]); + // shortcut syntax for public (exposed) methods (?op=plugin--pmethod&...params) + if (strpos($method, PluginHost::PUBLIC_METHOD_DELIMITER) !== false) { + list ($plugin, $pmethod) = explode(PluginHost::PUBLIC_METHOD_DELIMITER, $method, 2); + + // TODO: better implementation that won't modify $_REQUEST + $_REQUEST["plugin"] = $plugin; + $_REQUEST["pmethod"] = $pmethod; + + $method = "pluginhandler"; + } + $override = PluginHost::getInstance()->lookup_handler("public", $method); if ($override) { -- cgit v1.2.3-54-g00ecf From e4609c18efceebb1e021d814f53061ada7f6489a Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Wed, 17 Feb 2021 21:44:21 +0300 Subject: * add (disabled) shortcut syntax for plugin methods * add controls shortcut for pluginhandler tags * add similar shortcut for frontend * allow plugins to selectively exclude their methods from CSRF checking --- backend.php | 11 +++++++++++ classes/plugin.php | 4 ++++ classes/pluginhandler.php | 2 +- classes/pluginhost.php | 13 ++++++++++++- include/controls.php | 12 +++++++++++- js/App.js | 3 +++ plugins/af_proxy_http/init.php | 4 +--- plugins/af_psql_trgm/init.php | 4 +--- plugins/af_readability/init.js | 2 +- plugins/af_readability/init.php | 6 ++---- plugins/af_redditimgur/init.php | 9 +++++---- plugins/mail/init.php | 12 ++++-------- plugins/mail/mail.js | 2 +- plugins/mailto/init.js | 2 +- plugins/note/init.php | 4 +--- plugins/note/note.js | 2 +- plugins/nsfw/init.php | 4 +--- plugins/share/share.js | 8 +++----- plugins/share/share_prefs.js | 2 +- 19 files changed, 65 insertions(+), 41 deletions(-) (limited to 'classes/pluginhost.php') diff --git a/backend.php b/backend.php index 9ecc22914..e64c6561f 100644 --- a/backend.php +++ b/backend.php @@ -88,6 +88,17 @@ 5 => __("Power User"), 10 => __("Administrator")); + // shortcut syntax for plugin methods (?op=plugin--pmethod&...params) + /* if (strpos($op, PluginHost::PUBLIC_METHOD_DELIMITER) !== false) { + list ($plugin, $pmethod) = explode(PluginHost::PUBLIC_METHOD_DELIMITER, $op, 2); + + // TODO: better implementation that won't modify $_REQUEST + $_REQUEST["plugin"] = $plugin; + $method = $pmethod; + $op = "pluginhandler"; + } */ + + // TODO: figure out if is this still needed $op = str_replace("-", "_", $op); $override = PluginHost::getInstance()->lookup_handler($op, $method); diff --git a/classes/plugin.php b/classes/plugin.php index 2416418cd..6c572467a 100644 --- a/classes/plugin.php +++ b/classes/plugin.php @@ -54,4 +54,8 @@ abstract class Plugin { return vsprintf($this->__($msgid), $args); } + + function csrf_ignore($method) { + return false; + } } diff --git a/classes/pluginhandler.php b/classes/pluginhandler.php index a0e60b4e6..608f80dcb 100644 --- a/classes/pluginhandler.php +++ b/classes/pluginhandler.php @@ -11,7 +11,7 @@ class PluginHandler extends Handler_Protected { if ($plugin) { if (method_exists($plugin, $method)) { - if (validate_csrf($csrf_token)) { + if (validate_csrf($csrf_token) || $plugin->csrf_ignore($method)) { $plugin->$method(); } else { user_error("Rejected ${plugin_name}->${method}(): invalid CSRF token.", E_USER_WARNING); diff --git a/classes/pluginhost.php b/classes/pluginhost.php index 097bf987c..065fa99c4 100755 --- a/classes/pluginhost.php +++ b/classes/pluginhost.php @@ -611,6 +611,17 @@ class PluginHost { $params)); } + // shortcut syntax (disabled for now) + /* function get_method_url(Plugin $sender, string $method, $params) { + return get_self_url_prefix() . "/backend.php?" . + http_build_query( + array_merge( + [ + "op" => strtolower(get_class($sender) . self::PUBLIC_METHOD_DELIMITER . $method), + ], + $params)); + } */ + // WARNING: endpoint in public.php, exposed to unauthenticated users function get_public_method_url(Plugin $sender, string $method, $params) { if ($sender->is_public_method($method)) { @@ -618,7 +629,7 @@ class PluginHost { http_build_query( array_merge( [ - "op" => strtolower(get_class($sender) . PluginHost::PUBLIC_METHOD_DELIMITER . $method), + "op" => strtolower(get_class($sender) . self::PUBLIC_METHOD_DELIMITER . $method), ], $params)); } else { diff --git a/include/controls.php b/include/controls.php index 4c60d94f3..d8506877b 100755 --- a/include/controls.php +++ b/include/controls.php @@ -11,6 +11,17 @@ return $rv; } + // shortcut syntax (disabled) + /* function pluginhandler_tags(\Plugin $plugin, string $method) { + return hidden_tag("op", strtolower(get_class($plugin) . \PluginHost::PUBLIC_METHOD_DELIMITER . $method)); + } */ + + function pluginhandler_tags(\Plugin $plugin, string $method) { + return hidden_tag("op", "pluginhandler") . + hidden_tag("plugin", strtolower(get_class($plugin))) . + hidden_tag("method", $method); + } + function button_tag(string $value, string $type, array $attributes = []) { return ""; } @@ -155,4 +166,3 @@ return $ret; } - diff --git a/js/App.js b/js/App.js index 9d8f6c275..aeca688b7 100644 --- a/js/App.js +++ b/js/App.js @@ -101,6 +101,9 @@ const App = { return dijit.getEnclosingWidget(elem.closest('.dijitDialog')); }, + getPhArgs(plugin, method, args = {}) { + return {...{op: "pluginhandler", plugin: plugin, method: method}, ...args}; + }, label_to_feed_id: function(label) { return this.LABEL_BASE_INDEX - 1 - Math.abs(label); }, diff --git a/plugins/af_proxy_http/init.php b/plugins/af_proxy_http/init.php index 5804e450f..d6cee5fcd 100644 --- a/plugins/af_proxy_http/init.php +++ b/plugins/af_proxy_http/init.php @@ -229,9 +229,7 @@ class Af_Proxy_Http extends Plugin { } "; - print \Controls\hidden_tag("op", "pluginhandler"); - print \Controls\hidden_tag("method", "save"); - print \Controls\hidden_tag("plugin", "af_proxy_http"); + print \Controls\pluginhandler_tags($this, "save"); $proxy_all = sql_bool_to_bool($this->host->get($this, "proxy_all")); print \Controls\checkbox_tag("proxy_all", $proxy_all); diff --git a/plugins/af_psql_trgm/init.php b/plugins/af_psql_trgm/init.php index 1d83ce5e0..bfbbdf49c 100644 --- a/plugins/af_psql_trgm/init.php +++ b/plugins/af_psql_trgm/init.php @@ -157,9 +157,7 @@ class Af_Psql_Trgm extends Plugin { } "; - print \Controls\hidden_tag("op", "pluginhandler"); - print \Controls\hidden_tag("method", "save"); - print \Controls\hidden_tag("plugin", "af_psql_trgm"); + print \Controls\pluginhandler_tags($this, "save"); print "

" . __("Global settings") . "

"; diff --git a/plugins/af_readability/init.js b/plugins/af_readability/init.js index 3155475cc..ff2d94e8b 100644 --- a/plugins/af_readability/init.js +++ b/plugins/af_readability/init.js @@ -16,7 +16,7 @@ Plugins.Af_Readability = { Notify.progress("Loading, please wait..."); - xhrJson("backend.php",{ op: "pluginhandler", plugin: "af_readability", method: "embed", param: id }, (reply) => { + xhrJson("backend.php", App.getPhArgs("af_readability", "embed", {id: id}), (reply) => { if (content && reply.content) { content.setAttribute(self.orig_attr_name, content.innerHTML); diff --git a/plugins/af_readability/init.php b/plugins/af_readability/init.php index aeef8cddc..43d064fc7 100755 --- a/plugins/af_readability/init.php +++ b/plugins/af_readability/init.php @@ -67,9 +67,7 @@ class Af_Readability extends Plugin {
- - - + -
- - "; - print "window.close();"; - print ""; - - } else { - $title = htmlspecialchars(clean($_REQUEST["title"])); - $url = htmlspecialchars(clean($_REQUEST["url"])); - - ?> - - - - - -
- - -
- -
- - -
- -
- - -
- -
- - -
-
- -
- -
- - - -
- - - - - - -
- - - -
- - " /> -
- -
- - - "/> -
- -
- -
- - - -
- -
- "; - } - function login() { if (!SINGLE_USER_MODE) { @@ -565,160 +406,6 @@ class Handler_Public extends Handler { } } - function subscribe() { - if (SINGLE_USER_MODE) { - UserHelper::login_sequence(); - } - - if (!empty($_SESSION["uid"])) { - - $feed_url = clean($_REQUEST["feed_url"] ?? ""); - $csrf_token = clean($_POST["csrf_token"] ?? ""); - - header('Content-Type: text/html; charset=utf-8'); - ?> - - - - Tiny Tiny RSS - - - - - - - - -
-

-
- -
- - -
- - -
- - - - -
- %s.", $feed_url)); - break; - case 1: - print_notice(T_sprintf("Subscribed to %s.", $feed_url)); - break; - case 2: - print_error(T_sprintf("Could not subscribe to %s.", $feed_url)); - break; - case 3: - print_error(T_sprintf("No feeds found in %s.", $feed_url)); - break; - case 4: - $feed_urls = $rc["feeds"]; - break; - case 5: - print_error(T_sprintf("Could not subscribe to %s.
Can't download the Feed URL.", $feed_url)); - break; - } - - if ($feed_urls) { - - print "
"; - print ""; - print \Controls\hidden_tag("csrf_token", $_SESSION["csrf_token"]); - - print "
"; - print ""; - print ""; - print "
"; - - print ""; - print "".__("Return to Tiny Tiny RSS").""; - - print "
"; - } - - $tp_uri = get_self_url_prefix() . "/prefs.php"; - - if ($rc['code'] <= 2){ - $sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE - feed_url = ? AND owner_uid = ?"); - $sth->execute([$feed_url, $_SESSION['uid']]); - $row = $sth->fetch(); - - $feed_id = $row["id"]; - } else { - $feed_id = 0; - } - - if ($feed_id) { - print "
- - - - - ".__("Return to Tiny Tiny RSS")." -
"; - } - } - - print "
"; - - } else { - $this->render_login_form(); - } - } - function index() { header("Content-Type: text/plain"); print error_json(13); @@ -928,7 +615,7 @@ class Handler_Public extends Handler { if (!SINGLE_USER_MODE && $_SESSION["access_level"] < 10) { $_SESSION["login_error_msg"] = __("Your access level is insufficient to run this script."); - $this->render_login_form(); + $this->_render_login_form(); exit; } @@ -1066,7 +753,7 @@ class Handler_Public extends Handler { } } - private function make_article_tag_uri($id, $timestamp) { + private function _make_article_tag_uri($id, $timestamp) { $timestamp = date("Y-m-d", strtotime($timestamp)); @@ -1108,7 +795,7 @@ class Handler_Public extends Handler { } } - static function render_login_form() { + static function _render_login_form() { header('Cache-Control: public'); require_once "login_form.php"; diff --git a/classes/pluginhost.php b/classes/pluginhost.php index 065fa99c4..d50c5a706 100755 --- a/classes/pluginhost.php +++ b/classes/pluginhost.php @@ -599,7 +599,7 @@ class PluginHost { } // handled by classes/pluginhandler.php, requires valid session - function get_method_url(Plugin $sender, string $method, $params) { + function get_method_url(Plugin $sender, string $method, $params = []) { return get_self_url_prefix() . "/backend.php?" . http_build_query( array_merge( @@ -623,7 +623,7 @@ class PluginHost { } */ // WARNING: endpoint in public.php, exposed to unauthenticated users - function get_public_method_url(Plugin $sender, string $method, $params) { + function get_public_method_url(Plugin $sender, string $method, $params = []) { if ($sender->is_public_method($method)) { return get_self_url_prefix() . "/public.php?" . http_build_query( diff --git a/classes/userhelper.php b/classes/userhelper.php index 42d50a0f4..7fe1e5557 100644 --- a/classes/userhelper.php +++ b/classes/userhelper.php @@ -107,7 +107,7 @@ class UserHelper { if (empty($_SESSION["uid"])) { UserHelper::logout(); - Handler_Public::render_login_form(); + Handler_Public::_render_login_form(); exit; } diff --git a/include/controls.php b/include/controls.php index a60b1e0b0..ae5fba739 100755 --- a/include/controls.php +++ b/include/controls.php @@ -16,6 +16,10 @@ return hidden_tag("op", strtolower(get_class($plugin) . \PluginHost::PUBLIC_METHOD_DELIMITER . $method)); } */ + function public_method_tags(\Plugin $plugin, string $method) { + return hidden_tag("op", strtolower(get_class($plugin) . \PluginHost::PUBLIC_METHOD_DELIMITER . $method)); + } + function pluginhandler_tags(\Plugin $plugin, string $method) { return hidden_tag("op", "pluginhandler") . hidden_tag("plugin", strtolower(get_class($plugin))) . diff --git a/plugins/bookmarklets/init.php b/plugins/bookmarklets/init.php index a9dc3e69d..4c3bbf4cc 100644 --- a/plugins/bookmarklets/init.php +++ b/plugins/bookmarklets/init.php @@ -16,21 +16,338 @@ class Bookmarklets extends Plugin { $host->add_hook($host::HOOK_PREFS_TAB, $this); } - private function subscribe_to_feed_url() { - $url_path = get_self_url_prefix() . - "/public.php?op=subscribe&feed_url=%s"; - return $url_path; + function is_public_method($method) { + return in_array($method, ["subscribe", "sharepopup"]); } + function subscribe() { + if (SINGLE_USER_MODE) { + UserHelper::login_sequence(); + } + + if (!empty($_SESSION["uid"])) { + + $feed_url = clean($_REQUEST["feed_url"] ?? ""); + $csrf_token = clean($_POST["csrf_token"] ?? ""); + + header('Content-Type: text/html; charset=utf-8'); + ?> + + + + <?= __("Subscribe to feed...") ?> + + + + + + + + + + + +
+

+
+ +
+ + + +
+ + +
+ + + + +
+ %s.", $feed_url)); + break; + case 1: + print_notice(T_sprintf("Subscribed to %s.", $feed_url)); + break; + case 2: + print_error(T_sprintf("Could not subscribe to %s.", $feed_url)); + break; + case 3: + print_error(T_sprintf("No feeds found in %s.", $feed_url)); + break; + case 4: + $feed_urls = $rc["feeds"]; + break; + case 5: + print_error(T_sprintf("Could not subscribe to %s.
Can't download the Feed URL.", $feed_url)); + break; + } + + if ($feed_urls) { + + print "
"; + print \Controls\public_method_tags($this, "subscribe"); + print \Controls\hidden_tag("csrf_token", $_SESSION["csrf_token"]); + + print "
"; + print ""; + print ""; + print "
"; + + print ""; + print "".__("Return to Tiny Tiny RSS").""; + + print "
"; + } + + $tp_uri = get_self_url_prefix() . "/prefs.php"; + + if ($rc['code'] <= 2){ + $sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE + feed_url = ? AND owner_uid = ?"); + $sth->execute([$feed_url, $_SESSION['uid']]); + $row = $sth->fetch(); + + $feed_id = $row["id"]; + } else { + $feed_id = 0; + } + + if ($feed_id) { + print "
+ + + + + ".__("Return to Tiny Tiny RSS")." +
"; + } + } + + print "
"; + } else { + Handler_Public::_render_login_form(); + } + } + + function sharepopup() { + if (SINGLE_USER_MODE) { + UserHelper::login_sequence(); + } + + header('Content-Type: text/html; charset=utf-8'); + ?> + + + + <?= __("Share with Tiny Tiny RSS") ?> + + + + + + + + + + + +
+ + "; + print "window.close();"; + print ""; + + } else { + $title = htmlspecialchars(clean($_REQUEST["title"])); + $url = htmlspecialchars(clean($_REQUEST["url"])); + + ?> +
+ + + + + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + + +
+ +
+ +
+ + "window.close()"]) ?> + +
+ +
+ + +
+ + + +
+ + " /> +
+ +
+ + + "/> +
+ +
+ +
+ + + +
+ +
+ +
+ + "; + subscribe_to_feed_url()); + $bm_subscribe_url = $this->host->get_public_method_url($this, "subscribe"); + $bm_share_url = $this->host->get_public_method_url($this, "sharepopup"); + $confirm_str = str_replace("'", "\'", __('Subscribe to %s in Tiny Tiny RSS?')); - $bm_subscribe_url = htmlspecialchars("javascript:{if(confirm('$confirm_str'.replace('%s',window.location.href)))window.location.href='$bm_subscribe_url'+encodeURIComponent(window.location.href)}"); - $bm_share_url = htmlspecialchars("javascript:(function(){var d=document,w=window,e=w.getSelection,k=d.getSelection,x=d.selection,s=(e?e():(k)?k():(x?x.createRange().text:0)),f='".get_self_url_prefix()."/public.php?op=sharepopup',l=d.location,e=encodeURIComponent,g=f+'&title='+((e(s))?e(s):e(document.title))+'&url='+e(l.href);function a(){if(!w.open(g,'t','toolbar=0,resizable=0,scrollbars=1,status=1,width=500,height=250')){l.href=g;}}a();})()"); + $bm_subscribe_url = htmlspecialchars("javascript:{if(confirm('$confirm_str'.replace('%s',window.location.href)))window.location.href='$bm_subscribe_url&feed_url='+encodeURIComponent(window.location.href)}"); + $bm_share_url = htmlspecialchars("javascript:(function(){var d=document,w=window,e=w.getSelection,k=d.getSelection,x=d.selection,s=(e?e():(k)?k():(x?x.createRange().text:0)),f='$bm_share_url',l=d.location,e=encodeURIComponent,g=f+'&title='+((e(s))?e(s):e(document.title))+'&url='+e(l.href);function a(){if(!w.open(g,'t','toolbar=0,resizable=0,scrollbars=1,status=1,width=500,height=250')){l.href=g;}}a();})()"); + + //$bm_subscribe_url = str_replace('%s', '', $this->subscribe_to_feed_url()); + //$confirm_str = str_replace("'", "\'", __('Subscribe to %s in Tiny Tiny RSS?')); + //$bm_subscribe_url = htmlspecialchars("javascript:{if(confirm('$confirm_str'.replace('%s',window.location.href)))window.location.href='$bm_subscribe_url'+encodeURIComponent(window.location.href)}"); + + //$bm_share_url = htmlspecialchars("javascript:(function(){var d=document,w=window,e=w.getSelection,k=d.getSelection,x=d.selection,s=(e?e():(k)?k():(x?x.createRange().text:0)),f='".get_self_url_prefix()."/public.php?op=sharepopup',l=d.location,e=encodeURIComponent,g=f+'&title='+((e(s))?e(s):e(document.title))+'&url='+e(l.href);function a(){if(!w.open(g,'t','toolbar=0,resizable=0,scrollbars=1,status=1,width=500,height=250')){l.href=g;}}a();})()"); ?>
Date: Mon, 22 Feb 2021 10:00:50 +0300 Subject: reinstate HOOK_RENDER_ENCLOSURE --- classes/article.php | 23 ++++++++++++++++++----- classes/pluginhost.php | 4 ++-- js/Article.js | 6 +----- plugins/af_youtube_embed/init.php | 6 +++--- 4 files changed, 24 insertions(+), 15 deletions(-) (limited to 'classes/pluginhost.php') diff --git a/classes/article.php b/classes/article.php index dd1470caa..acd83694c 100755 --- a/classes/article.php +++ b/classes/article.php @@ -343,6 +343,7 @@ class Article extends Handler_Protected { } $rv = [ + 'formatted' => '', 'entries' => [] ]; @@ -358,12 +359,24 @@ class Article extends Handler_Protected { // this is highly approximate $enc["filename"] = basename($enc["content_url"]); - PluginHost::getInstance()->chain_hooks_callback(PluginHost::HOOK_ENCLOSURE_ENTRY, - function ($result) use (&$enc) { - $enc = $result; + $rendered_enc = ""; + PluginHost::getInstance()->chain_hooks_callback(PluginHost::HOOK_RENDER_ENCLOSURE, + function ($result) use (&$rendered_enc) { + $rendered_enc = $result; }, - $enc, $id); - array_push($rv['entries'], $enc); + $enc, $id, $rv); + + if ($rendered_enc) { + $rv['formatted'] .= $rendered_enc; + } else { + PluginHost::getInstance()->chain_hooks_callback(PluginHost::HOOK_ENCLOSURE_ENTRY, + function ($result) use (&$enc) { + $enc = $result; + }, + $enc, $id, $rv); + + array_push($rv['entries'], $enc); + } } return $rv; diff --git a/classes/pluginhost.php b/classes/pluginhost.php index d50c5a706..a05938111 100755 --- a/classes/pluginhost.php +++ b/classes/pluginhost.php @@ -51,11 +51,11 @@ class PluginHost { const HOOK_FORMAT_ENCLOSURES = "hook_format_enclosures"; // hook__format_enclosures($rv, $result, $id, $always_display_enclosures, $article_content, $hide_images) (byref) const HOOK_SUBSCRIBE_FEED = "hook_subscribe_feed"; // hook_subscribe_feed($contents, $url, $auth_login, $auth_pass) (byref) const HOOK_HEADLINES_BEFORE = "hook_headlines_before"; // hook_headlines_before($feed, $is_cat, $qfh_ret) - const HOOK_RENDER_ENCLOSURE = "hook_render_enclosure"; // hook_render_enclosure($entry, $hide_images) + const HOOK_RENDER_ENCLOSURE = "hook_render_enclosure"; // hook_render_enclosure($entry, $id, $rv) const HOOK_ARTICLE_FILTER_ACTION = "hook_article_filter_action"; // hook_article_filter_action($article, $action) const HOOK_ARTICLE_EXPORT_FEED = "hook_article_export_feed"; // hook_article_export_feed($line, $feed, $is_cat, $owner_uid) (byref) const HOOK_MAIN_TOOLBAR_BUTTON = "hook_main_toolbar_button"; // hook_main_toolbar_button() - const HOOK_ENCLOSURE_ENTRY = "hook_enclosure_entry"; // hook_enclosure_entry($row, $id) (byref) + const HOOK_ENCLOSURE_ENTRY = "hook_enclosure_entry"; // hook_enclosure_entry($entry, $id, $rv) (byref) const HOOK_FORMAT_ARTICLE = "hook_format_article"; // hook_format_article($html, $row) const HOOK_FORMAT_ARTICLE_CDM = "hook_format_article_cdm"; /* RIP */ const HOOK_FEED_BASIC_INFO = "hook_feed_basic_info"; // hook_feed_basic_info($basic_info, $fetch_url, $owner_uid, $feed_id, $auth_login, $auth_pass) (byref) diff --git a/js/Article.js b/js/Article.js index d039882ec..5f695561c 100644 --- a/js/Article.js +++ b/js/Article.js @@ -150,12 +150,8 @@ const Article = { ).join("")}`; }, renderEnclosures: function (enclosures) { - - // enclosure list was handled by backend (HOOK_FORMAT_ENCLOSURES) - if (enclosures.formatted) - return enclosures.formatted; - return ` + ${enclosures.formatted} ${enclosures.can_inline ? `
${enclosures.entries.map((enc) => { diff --git a/plugins/af_youtube_embed/init.php b/plugins/af_youtube_embed/init.php index db82dc9f5..6309aac02 100644 --- a/plugins/af_youtube_embed/init.php +++ b/plugins/af_youtube_embed/init.php @@ -23,9 +23,9 @@ class Af_Youtube_Embed extends Plugin { $matches = array(); - if (preg_match("/\/\/www\.youtube\.com\/v\/([\w-]+)/", $entry["url"], $matches) || - preg_match("/\/\/www\.youtube\.com\/watch?v=([\w-]+)/", $entry["url"], $matches) || - preg_match("/\/\/youtu.be\/([\w-]+)/", $entry["url"], $matches)) { + if (preg_match("/\/\/www\.youtube\.com\/v\/([\w-]+)/", $entry["content_url"], $matches) || + preg_match("/\/\/www\.youtube\.com\/watch?v=([\w-]+)/", $entry["content_url"], $matches) || + preg_match("/\/\/youtu.be\/([\w-]+)/", $entry["content_url"], $matches)) { $vid_id = $matches[1]; -- cgit v1.2.3-54-g00ecf From be4e7b13403666fc477d4b563ea8c075d0fd2022 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Mon, 22 Feb 2021 14:41:09 +0300 Subject: fix several issues reported by phpstan --- api/index.php | 4 ++-- classes/api.php | 2 +- classes/digest.php | 9 --------- classes/feeds.php | 6 ------ classes/handler/public.php | 10 +++++----- classes/pluginhost.php | 3 ++- classes/pref/prefs.php | 7 ------- include/functions.php | 8 ++++---- include/sanity_check.php | 6 +++--- include/sanity_config.php | 4 ++-- include/sessions.php | 8 ++++---- phpstan.neon | 4 +++- plugins/af_fsckportal/init.php | 5 +---- plugins/af_redditimgur/init.php | 5 ++++- update.php | 4 ++-- utils/regen_config_checks.sh | 4 ++-- 16 files changed, 35 insertions(+), 54 deletions(-) (limited to 'classes/pluginhost.php') diff --git a/api/index.php b/api/index.php index eb79422f9..1b713d561 100644 --- a/api/index.php +++ b/api/index.php @@ -18,8 +18,8 @@ require_once "functions.php"; require_once "sessions.php"; - ini_set('session.use_cookies', 0); - ini_set("session.gc_maxlifetime", 86400); + ini_set('session.use_cookies', "0"); + ini_set("session.gc_maxlifetime", "86400"); ob_start(); diff --git a/classes/api.php b/classes/api.php index 03eea1927..5677cb908 100755 --- a/classes/api.php +++ b/classes/api.php @@ -292,7 +292,7 @@ class API extends Handler { $sanitize_content = !isset($_REQUEST["sanitize"]) || self::_param_to_bool($_REQUEST["sanitize"]); - if ($article_ids) { + if (count($article_ids) > 0) { $article_qmarks = arr_qmarks($article_ids); diff --git a/classes/digest.php b/classes/digest.php index 77eb92c54..e0c23d705 100644 --- a/classes/digest.php +++ b/classes/digest.php @@ -1,12 +1,6 @@ addBlock('enclosure'); } } else { - $tpl->setVariable('ARTICLE_ENCLOSURE_URL', null, true); - $tpl->setVariable('ARTICLE_ENCLOSURE_TYPE', null, true); - $tpl->setVariable('ARTICLE_ENCLOSURE_LENGTH', null, true); + $tpl->setVariable('ARTICLE_ENCLOSURE_URL', "", true); + $tpl->setVariable('ARTICLE_ENCLOSURE_TYPE', "", true); + $tpl->setVariable('ARTICLE_ENCLOSURE_LENGTH', "", true); } list ($og_image, $og_stream) = Article::_get_image($enclosures, $line['content'], $feed_site_url); @@ -207,8 +207,8 @@ class Handler_Public extends Handler { $article['content'] = Sanitizer::sanitize($line["content"], false, $owner_uid, $feed_site_url, false, $line["id"]); $article['updated'] = date('c', strtotime($line["updated"])); - if ($line['note']) $article['note'] = $line['note']; - if ($article['author']) $article['author'] = $line['author']; + if (!empty($line['note'])) $article['note'] = $line['note']; + if (!empty($line['author'])) $article['author'] = $line['author']; if (count($line["tags"]) > 0) { $article['tags'] = array(); diff --git a/classes/pluginhost.php b/classes/pluginhost.php index a05938111..5121c8491 100755 --- a/classes/pluginhost.php +++ b/classes/pluginhost.php @@ -108,8 +108,9 @@ class PluginHost { return false; } + // needed for compatibility with API 2 (?) function get_dbh() { - return Db::get(); + return false; } function get_pdo(): PDO { diff --git a/classes/pref/prefs.php b/classes/pref/prefs.php index a26281fee..adb249dac 100644 --- a/classes/pref/prefs.php +++ b/classes/pref/prefs.php @@ -311,13 +311,6 @@ class Pref_Prefs extends Handler_Protected { - -
- - -
- -