]> git.wh0rd.org Git - tt-rss.git/commitdiff
rename plugin main class files
authorAndrew Dolgov <fox@madoka.volgo-balt.ru>
Sun, 30 Dec 2012 09:36:40 +0000 (13:36 +0400)
committerAndrew Dolgov <fox@madoka.volgo-balt.ru>
Sun, 30 Dec 2012 09:36:40 +0000 (13:36 +0400)
49 files changed:
classes/pluginhost.php
plugins/af_explosm/af_explosm.php [deleted file]
plugins/af_explosm/init.php [new file with mode: 0644]
plugins/af_gocomics/af_gocomics.php [deleted file]
plugins/af_gocomics/init.php [new file with mode: 0644]
plugins/af_pennyarcade/af_pennyarcade.php [deleted file]
plugins/af_pennyarcade/init.php [new file with mode: 0644]
plugins/af_redditimgur/af_redditimgur.php [deleted file]
plugins/af_redditimgur/init.php [new file with mode: 0644]
plugins/auth_imap/auth_imap.php [deleted file]
plugins/auth_imap/init.php [new file with mode: 0644]
plugins/auth_internal/auth_internal.php [deleted file]
plugins/auth_internal/init.php [new file with mode: 0644]
plugins/auth_remote/auth_remote.php [deleted file]
plugins/auth_remote/init.php [new file with mode: 0644]
plugins/digest/digest.php [deleted file]
plugins/digest/init.php [new file with mode: 0644]
plugins/example/example.php [deleted file]
plugins/example/init.php [new file with mode: 0644]
plugins/example_feed/example_feed.php [deleted file]
plugins/example_feed/init.php [new file with mode: 0644]
plugins/example_routing/example_routing.php [deleted file]
plugins/example_routing/init.php [new file with mode: 0644]
plugins/flattr/flattr.php [deleted file]
plugins/flattr/init.php [new file with mode: 0644]
plugins/googleplus/googleplus.php [deleted file]
plugins/googleplus/init.php [new file with mode: 0644]
plugins/identica/identica.php [deleted file]
plugins/identica/init.php [new file with mode: 0644]
plugins/import_export/import_export.php [deleted file]
plugins/import_export/init.php [new file with mode: 0644]
plugins/instances/init.php [new file with mode: 0644]
plugins/instances/instances.php [deleted file]
plugins/mail/init.php [new file with mode: 0644]
plugins/mail/mail.php [deleted file]
plugins/note/init.php [new file with mode: 0644]
plugins/note/note.php [deleted file]
plugins/owncloud/init.php [new file with mode: 0644]
plugins/owncloud/owncloud.php [deleted file]
plugins/pinterest/init.php [new file with mode: 0644]
plugins/pinterest/pinterest.php [deleted file]
plugins/pocket/init.php [new file with mode: 0644]
plugins/pocket/pocket.php [deleted file]
plugins/share/init.php [new file with mode: 0644]
plugins/share/share.php [deleted file]
plugins/swap_jk/init.php [new file with mode: 0644]
plugins/swap_jk/swap_jk.php [deleted file]
plugins/updater/init.php [new file with mode: 0644]
plugins/updater/updater.php [deleted file]

index b304091696261584db2aff1b3477f1c2a5fb78af..a1ad7ef078ef5a8f48e81f173102c336205c7d7b 100644 (file)
@@ -90,7 +90,7 @@ class PluginHost {
                foreach ($plugins as $class) {
                        $class = trim($class);
                        $class_file = strtolower(basename($class));
-                       $file = dirname(__FILE__)."/../plugins/$class_file/$class_file.php";
+                       $file = dirname(__FILE__)."/../plugins/$class_file/init.php";
 
                        if (!isset($this->plugins[$class])) {
                                if (file_exists($file)) require_once $file;
diff --git a/plugins/af_explosm/af_explosm.php b/plugins/af_explosm/af_explosm.php
deleted file mode 100644 (file)
index d3da260..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-<?php
-class Af_Explosm extends Plugin {
-
-       private $link;
-       private $host;
-
-       function about() {
-               return array(1.0,
-                       "Strip unnecessary stuff from Cyanide and Happiness feeds",
-                       "fox");
-       }
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-
-               $host->add_hook($host::HOOK_ARTICLE_FILTER, $this);
-       }
-
-       function hook_article_filter($article) {
-               $owner_uid = $article["owner_uid"];
-
-               if (strpos($article["link"], "explosm.net/comics") !== FALSE &&
-                               strpos($article["guid"], "explosm,$owner_uid:") === FALSE) {
-
-                       $doc = new DOMDocument();
-                       @$doc->loadHTML(fetch_file_contents($article["link"]));
-
-                       $basenode = false;
-
-                       if ($doc) {
-                               $xpath = new DOMXPath($doc);
-                               $entries = $xpath->query('(//img[@src])'); // we might also check for img[@class='strip'] I guess...
-
-                               $matches = array();
-
-                               foreach ($entries as $entry) {
-
-                                       if (preg_match("/(http:\/\/.*\/db\/files\/Comics\/.*)/i", $entry->getAttribute("src"), $matches)) {
-
-                                               $basenode = $entry;
-                                               break;
-                                       }
-                               }
-
-                               if ($basenode) {
-                                       $article["content"] = $doc->saveXML($basenode, LIBXML_NOEMPTYTAG);
-
-                                       // we need to update guid with owner_uid because our local article is different from the one
-                                       // other users with this plugin disabled might get
-                                       $article["guid"] = "explosm,$owner_uid:" . $article["guid"];
-                               }
-                       }
-               }
-
-               return $article;
-       }
-}
-?>
diff --git a/plugins/af_explosm/init.php b/plugins/af_explosm/init.php
new file mode 100644 (file)
index 0000000..d3da260
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+class Af_Explosm extends Plugin {
+
+       private $link;
+       private $host;
+
+       function about() {
+               return array(1.0,
+                       "Strip unnecessary stuff from Cyanide and Happiness feeds",
+                       "fox");
+       }
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_hook($host::HOOK_ARTICLE_FILTER, $this);
+       }
+
+       function hook_article_filter($article) {
+               $owner_uid = $article["owner_uid"];
+
+               if (strpos($article["link"], "explosm.net/comics") !== FALSE &&
+                               strpos($article["guid"], "explosm,$owner_uid:") === FALSE) {
+
+                       $doc = new DOMDocument();
+                       @$doc->loadHTML(fetch_file_contents($article["link"]));
+
+                       $basenode = false;
+
+                       if ($doc) {
+                               $xpath = new DOMXPath($doc);
+                               $entries = $xpath->query('(//img[@src])'); // we might also check for img[@class='strip'] I guess...
+
+                               $matches = array();
+
+                               foreach ($entries as $entry) {
+
+                                       if (preg_match("/(http:\/\/.*\/db\/files\/Comics\/.*)/i", $entry->getAttribute("src"), $matches)) {
+
+                                               $basenode = $entry;
+                                               break;
+                                       }
+                               }
+
+                               if ($basenode) {
+                                       $article["content"] = $doc->saveXML($basenode, LIBXML_NOEMPTYTAG);
+
+                                       // we need to update guid with owner_uid because our local article is different from the one
+                                       // other users with this plugin disabled might get
+                                       $article["guid"] = "explosm,$owner_uid:" . $article["guid"];
+                               }
+                       }
+               }
+
+               return $article;
+       }
+}
+?>
diff --git a/plugins/af_gocomics/af_gocomics.php b/plugins/af_gocomics/af_gocomics.php
deleted file mode 100644 (file)
index 1dd1886..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-<?php
-class Af_GoComics extends Plugin {
-
-       private $link;
-       private $host;
-
-       function about() {
-               return array(1.0,
-                       "Strip unnecessary stuff from gocomics feeds",
-                       "fox");
-       }
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-
-               $host->add_hook($host::HOOK_ARTICLE_FILTER, $this);
-       }
-
-       function hook_article_filter($article) {
-               $owner_uid = $article["owner_uid"];
-
-               if (strpos($article["guid"], "gocomics.com") !== FALSE && strpos($article["guid"], "gocomics,$owner_uid:") === FALSE) {
-                       $doc = new DOMDocument();
-                       @$doc->loadHTML(fetch_file_contents($article["link"]));
-
-                       $basenode = false;
-
-                       if ($doc) {
-                               $xpath = new DOMXPath($doc);
-                               $entries = $xpath->query('(//img[@src])'); // we might also check for img[@class='strip'] I guess...
-
-                               $matches = array();
-
-                               foreach ($entries as $entry) {
-
-                                       if (preg_match("/(http:\/\/assets.amuniversal.com\/.*)/i", $entry->getAttribute("src"), $matches)) {
-
-                                               $entry->setAttribute("src", $matches[0]);
-                                               $basenode = $entry;
-                                               break;
-                                       }
-                               }
-
-                               if ($basenode) {
-                                       $article["content"] = $doc->saveXML($basenode, LIBXML_NOEMPTYTAG);
-
-                                       // we need to update guid with owner_uid because our local article is different from the one
-                                       // other users with this plugin disabled might get
-                                       $article["guid"] = "gocomics,$owner_uid:" . $article["guid"];
-                               }
-                       }
-               }
-
-               return $article;
-       }
-}
-?>
diff --git a/plugins/af_gocomics/init.php b/plugins/af_gocomics/init.php
new file mode 100644 (file)
index 0000000..1dd1886
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+class Af_GoComics extends Plugin {
+
+       private $link;
+       private $host;
+
+       function about() {
+               return array(1.0,
+                       "Strip unnecessary stuff from gocomics feeds",
+                       "fox");
+       }
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_hook($host::HOOK_ARTICLE_FILTER, $this);
+       }
+
+       function hook_article_filter($article) {
+               $owner_uid = $article["owner_uid"];
+
+               if (strpos($article["guid"], "gocomics.com") !== FALSE && strpos($article["guid"], "gocomics,$owner_uid:") === FALSE) {
+                       $doc = new DOMDocument();
+                       @$doc->loadHTML(fetch_file_contents($article["link"]));
+
+                       $basenode = false;
+
+                       if ($doc) {
+                               $xpath = new DOMXPath($doc);
+                               $entries = $xpath->query('(//img[@src])'); // we might also check for img[@class='strip'] I guess...
+
+                               $matches = array();
+
+                               foreach ($entries as $entry) {
+
+                                       if (preg_match("/(http:\/\/assets.amuniversal.com\/.*)/i", $entry->getAttribute("src"), $matches)) {
+
+                                               $entry->setAttribute("src", $matches[0]);
+                                               $basenode = $entry;
+                                               break;
+                                       }
+                               }
+
+                               if ($basenode) {
+                                       $article["content"] = $doc->saveXML($basenode, LIBXML_NOEMPTYTAG);
+
+                                       // we need to update guid with owner_uid because our local article is different from the one
+                                       // other users with this plugin disabled might get
+                                       $article["guid"] = "gocomics,$owner_uid:" . $article["guid"];
+                               }
+                       }
+               }
+
+               return $article;
+       }
+}
+?>
diff --git a/plugins/af_pennyarcade/af_pennyarcade.php b/plugins/af_pennyarcade/af_pennyarcade.php
deleted file mode 100644 (file)
index ec03990..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-<?php
-class Af_PennyArcade extends Plugin {
-
-       private $link;
-       private $host;
-
-       function about() {
-               return array(1.0,
-                       "Strip unnecessary stuff from PA feeds",
-                       "fox");
-       }
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-
-               $host->add_hook($host::HOOK_ARTICLE_FILTER, $this);
-       }
-
-       function hook_article_filter($article) {
-               $owner_uid = $article["owner_uid"];
-
-               if (strpos($article["link"], "penny-arcade.com") !== FALSE && strpos($article["title"], "Comic:") !== FALSE &&
-                               strpos($article["guid"], "pennyarcade,$owner_uid:") === FALSE) {
-
-                       $doc = new DOMDocument();
-                       @$doc->loadHTML(fetch_file_contents($article["link"]));
-
-                       $basenode = false;
-
-                       if ($doc) {
-                               $xpath = new DOMXPath($doc);
-                               $entries = $xpath->query('(//img[@src])'); // we might also check for img[@class='strip'] I guess...
-
-                               $matches = array();
-
-                               foreach ($entries as $entry) {
-
-                                       if (preg_match("/(http:\/\/art.penny-arcade.com\/.*)/i", $entry->getAttribute("src"), $matches)) {
-
-                                               $basenode = $entry;
-                                               break;
-                                       }
-                               }
-
-                               if ($basenode) {
-                                       $article["content"] = $doc->saveXML($basenode, LIBXML_NOEMPTYTAG);
-
-                                       // we need to update guid with owner_uid because our local article is different from the one
-                                       // other users with this plugin disabled might get
-                                       $article["guid"] = "pennyarcade,$owner_uid:" . $article["guid"];
-                               }
-                       }
-               }
-
-               return $article;
-       }
-}
-?>
diff --git a/plugins/af_pennyarcade/init.php b/plugins/af_pennyarcade/init.php
new file mode 100644 (file)
index 0000000..ec03990
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+class Af_PennyArcade extends Plugin {
+
+       private $link;
+       private $host;
+
+       function about() {
+               return array(1.0,
+                       "Strip unnecessary stuff from PA feeds",
+                       "fox");
+       }
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_hook($host::HOOK_ARTICLE_FILTER, $this);
+       }
+
+       function hook_article_filter($article) {
+               $owner_uid = $article["owner_uid"];
+
+               if (strpos($article["link"], "penny-arcade.com") !== FALSE && strpos($article["title"], "Comic:") !== FALSE &&
+                               strpos($article["guid"], "pennyarcade,$owner_uid:") === FALSE) {
+
+                       $doc = new DOMDocument();
+                       @$doc->loadHTML(fetch_file_contents($article["link"]));
+
+                       $basenode = false;
+
+                       if ($doc) {
+                               $xpath = new DOMXPath($doc);
+                               $entries = $xpath->query('(//img[@src])'); // we might also check for img[@class='strip'] I guess...
+
+                               $matches = array();
+
+                               foreach ($entries as $entry) {
+
+                                       if (preg_match("/(http:\/\/art.penny-arcade.com\/.*)/i", $entry->getAttribute("src"), $matches)) {
+
+                                               $basenode = $entry;
+                                               break;
+                                       }
+                               }
+
+                               if ($basenode) {
+                                       $article["content"] = $doc->saveXML($basenode, LIBXML_NOEMPTYTAG);
+
+                                       // we need to update guid with owner_uid because our local article is different from the one
+                                       // other users with this plugin disabled might get
+                                       $article["guid"] = "pennyarcade,$owner_uid:" . $article["guid"];
+                               }
+                       }
+               }
+
+               return $article;
+       }
+}
+?>
diff --git a/plugins/af_redditimgur/af_redditimgur.php b/plugins/af_redditimgur/af_redditimgur.php
deleted file mode 100644 (file)
index a258f3c..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-<?php
-class Af_RedditImgur extends Plugin {
-
-       private $link;
-       private $host;
-
-       function about() {
-               return array(1.0,
-                       "Inline image links in Reddit RSS feeds",
-                       "fox");
-       }
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-
-               $host->add_hook($host::HOOK_ARTICLE_FILTER, $this);
-       }
-
-       function hook_article_filter($article) {
-
-               if (strpos($article["link"], "reddit.com/r/") !== FALSE) {
-                       $doc = new DOMDocument();
-                       @$doc->loadHTML($article["content"]);
-
-                       if ($doc) {
-                               $xpath = new DOMXPath($doc);
-                               $entries = $xpath->query('(//a[@href]|//img[@src])');
-
-                               foreach ($entries as $entry) {
-                                       if ($entry->hasAttribute("href")) {
-                                               if (preg_match("/\.(jpg|jpeg|gif|png)$/i", $entry->getAttribute("href"))) {
-
-                                                       $img = $doc->createElement('img');
-                                                       $img->setAttribute("src", $entry->getAttribute("href"));
-
-                                                       $entry->parentNode->replaceChild($img, $entry);
-                                               }
-                                       }
-
-                                       // remove tiny thumbnails
-                                       if ($entry->hasAttribute("src")) {
-                                               if ($entry->parentNode && $entry->parentNode->parentNode) {
-                                                       $entry->parentNode->parentNode->removeChild($entry->parentNode);
-                                               }
-                                       }
-                               }
-
-                               $node = $doc->getElementsByTagName('body')->item(0);
-
-                               if ($node) {
-                                       $article["content"] = $doc->saveXML($node, LIBXML_NOEMPTYTAG);
-                               }
-                       }
-               }
-
-               return $article;
-       }
-}
-?>
diff --git a/plugins/af_redditimgur/init.php b/plugins/af_redditimgur/init.php
new file mode 100644 (file)
index 0000000..a258f3c
--- /dev/null
@@ -0,0 +1,60 @@
+<?php
+class Af_RedditImgur extends Plugin {
+
+       private $link;
+       private $host;
+
+       function about() {
+               return array(1.0,
+                       "Inline image links in Reddit RSS feeds",
+                       "fox");
+       }
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_hook($host::HOOK_ARTICLE_FILTER, $this);
+       }
+
+       function hook_article_filter($article) {
+
+               if (strpos($article["link"], "reddit.com/r/") !== FALSE) {
+                       $doc = new DOMDocument();
+                       @$doc->loadHTML($article["content"]);
+
+                       if ($doc) {
+                               $xpath = new DOMXPath($doc);
+                               $entries = $xpath->query('(//a[@href]|//img[@src])');
+
+                               foreach ($entries as $entry) {
+                                       if ($entry->hasAttribute("href")) {
+                                               if (preg_match("/\.(jpg|jpeg|gif|png)$/i", $entry->getAttribute("href"))) {
+
+                                                       $img = $doc->createElement('img');
+                                                       $img->setAttribute("src", $entry->getAttribute("href"));
+
+                                                       $entry->parentNode->replaceChild($img, $entry);
+                                               }
+                                       }
+
+                                       // remove tiny thumbnails
+                                       if ($entry->hasAttribute("src")) {
+                                               if ($entry->parentNode && $entry->parentNode->parentNode) {
+                                                       $entry->parentNode->parentNode->removeChild($entry->parentNode);
+                                               }
+                                       }
+                               }
+
+                               $node = $doc->getElementsByTagName('body')->item(0);
+
+                               if ($node) {
+                                       $article["content"] = $doc->saveXML($node, LIBXML_NOEMPTYTAG);
+                               }
+                       }
+               }
+
+               return $article;
+       }
+}
+?>
diff --git a/plugins/auth_imap/auth_imap.php b/plugins/auth_imap/auth_imap.php
deleted file mode 100644 (file)
index cca279c..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-/* Requires php-imap
-       Put the following options in config.php:
-
-       define('IMAP_AUTH_SERVER', 'your.imap.server:port');
-       define('IMAP_AUTH_OPTIONS', '/tls/novalidate-cert/norsh');
-       // More about options: http://php.net/manual/ru/function.imap-open.php
-
-*/
-class Auth_Imap extends Plugin implements IAuthModule {
-
-       private $link;
-       private $host;
-       private $base;
-
-       function about() {
-               return array(1.0,
-                       "Authenticates against an IMAP server (configured in config.php)",
-                       "fox",
-                       true);
-       }
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-               $this->base = new Auth_Base($this->link);
-
-               $host->add_hook($host::HOOK_AUTH_USER, $this);
-       }
-
-       function authenticate($login, $password) {
-
-               if ($login && $password) {
-                       $imap = imap_open(
-                               "{".IMAP_AUTH_SERVER.IMAP_AUTH_OPTIONS."}INBOX",
-                               $login,
-                               $password);
-
-                       if ($imap) {
-                               imap_close($imap);
-
-                               return $this->base->auto_create_user($login);
-                       }
-               }
-
-               return false;
-       }
-
-}
-
-?>
diff --git a/plugins/auth_imap/init.php b/plugins/auth_imap/init.php
new file mode 100644 (file)
index 0000000..cca279c
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+/* Requires php-imap
+       Put the following options in config.php:
+
+       define('IMAP_AUTH_SERVER', 'your.imap.server:port');
+       define('IMAP_AUTH_OPTIONS', '/tls/novalidate-cert/norsh');
+       // More about options: http://php.net/manual/ru/function.imap-open.php
+
+*/
+class Auth_Imap extends Plugin implements IAuthModule {
+
+       private $link;
+       private $host;
+       private $base;
+
+       function about() {
+               return array(1.0,
+                       "Authenticates against an IMAP server (configured in config.php)",
+                       "fox",
+                       true);
+       }
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+               $this->base = new Auth_Base($this->link);
+
+               $host->add_hook($host::HOOK_AUTH_USER, $this);
+       }
+
+       function authenticate($login, $password) {
+
+               if ($login && $password) {
+                       $imap = imap_open(
+                               "{".IMAP_AUTH_SERVER.IMAP_AUTH_OPTIONS."}INBOX",
+                               $login,
+                               $password);
+
+                       if ($imap) {
+                               imap_close($imap);
+
+                               return $this->base->auto_create_user($login);
+                       }
+               }
+
+               return false;
+       }
+
+}
+
+?>
diff --git a/plugins/auth_internal/auth_internal.php b/plugins/auth_internal/auth_internal.php
deleted file mode 100644 (file)
index cf6c137..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-<?php
-class Auth_Internal extends Plugin implements IAuthModule {
-
-       private $link;
-       private $host;
-
-       function about() {
-               return array(1.0,
-                       "Authenticates against internal tt-rss database",
-                       "fox",
-                       true);
-       }
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-
-               $host->add_hook($host::HOOK_AUTH_USER, $this);
-       }
-
-       function authenticate($login, $password) {
-
-               $pwd_hash1 = encrypt_password($password);
-               $pwd_hash2 = encrypt_password($password, $login);
-               $login = db_escape_string($login);
-               $otp = db_escape_string($_REQUEST["otp"]);
-
-               if (get_schema_version($this->link) > 96) {
-                       if (!defined('AUTH_DISABLE_OTP') || !AUTH_DISABLE_OTP) {
-                               $result = db_query($this->link, "SELECT otp_enabled,salt FROM ttrss_users WHERE
-                                       login = '$login'");
-
-                               if (db_num_rows($result) > 0) {
-                                       require_once "lib/otphp/vendor/base32.php";
-                                       require_once "lib/otphp/lib/otp.php";
-                                       require_once "lib/otphp/lib/totp.php";
-
-                                       $base32 = new Base32();
-
-                                       $otp_enabled = sql_bool_to_bool(db_fetch_result($result, 0, "otp_enabled"));
-                                       $secret = $base32->encode(sha1(db_fetch_result($result, 0, "salt")));
-
-                                       $topt = new \OTPHP\TOTP($secret);
-                                       $otp_check = $topt->now();
-
-                                       if ($otp_enabled) {
-                                               if ($otp) {
-                                                       if ($otp != $otp_check) {
-                                                               return false;
-                                                       }
-                                               } else {
-                                                       $return = urlencode($_REQUEST["return"]);
-                                                       ?><html>
-                                                               <head><title>Tiny Tiny RSS</title></head>
-                                                       <body>
-                                                       <form action="public.php?return=<?php echo $return ?>"
-                                                                       method="POST">
-                                                               <input type="hidden" name="op" value="login">
-                                                               <input type="hidden" name="login" value="<?php echo htmlspecialchars($login) ?>">
-                                                               <input type="hidden" name="password" value="<?php echo htmlspecialchars($password) ?>">
-
-                                                               <label><?php echo __("Please enter your one time password:") ?></label>
-                                                               <input type="password" size="6" name="otp"/>
-                                                               <input type="submit" value="Continue"/>
-                                                       </form>
-                                                       <script type="text/javascript">
-                                                               document.forms[0].otp.focus();
-                                                       </script>
-                                                       <?php
-                                                       exit;
-                                               }
-                                       }
-                               }
-                       }
-               }
-
-               if (get_schema_version($this->link) > 87) {
-
-                       $result = db_query($this->link, "SELECT salt FROM ttrss_users WHERE
-                               login = '$login'");
-
-                       if (db_num_rows($result) != 1) {
-                               return false;
-                       }
-
-                       $salt = db_fetch_result($result, 0, "salt");
-
-                       if ($salt == "") {
-
-                               $query = "SELECT id
-                   FROM ttrss_users WHERE
-                                       login = '$login' AND (pwd_hash = '$pwd_hash1' OR
-                                       pwd_hash = '$pwd_hash2')";
-
-                               // verify and upgrade password to new salt base
-
-                               $result = db_query($this->link, $query);
-
-                               if (db_num_rows($result) == 1) {
-                                       // upgrade password to MODE2
-
-                                       $salt = substr(bin2hex(get_random_bytes(125)), 0, 250);
-                                       $pwd_hash = encrypt_password($password, $salt, true);
-
-                                       db_query($this->link, "UPDATE ttrss_users SET
-                                               pwd_hash = '$pwd_hash', salt = '$salt' WHERE login = '$login'");
-
-                                       $query = "SELECT id
-                           FROM ttrss_users WHERE
-                                               login = '$login' AND pwd_hash = '$pwd_hash'";
-
-                               } else {
-                                       return false;
-                               }
-
-                       } else {
-
-                               $pwd_hash = encrypt_password($password, $salt, true);
-
-                               $query = "SELECT id
-                        FROM ttrss_users WHERE
-                                       login = '$login' AND pwd_hash = '$pwd_hash'";
-
-                       }
-
-               } else {
-                       $query = "SELECT id
-                FROM ttrss_users WHERE
-                               login = '$login' AND (pwd_hash = '$pwd_hash1' OR
-                                       pwd_hash = '$pwd_hash2')";
-               }
-
-               $result = db_query($this->link, $query);
-
-               if (db_num_rows($result) == 1) {
-                       return db_fetch_result($result, 0, "id");
-               }
-
-               return false;
-       }
-
-       function check_password($owner_uid, $password) {
-               $owner_uid = db_escape_string($owner_uid);
-
-               $result = db_query($this->link, "SELECT salt,login FROM ttrss_users WHERE
-                       id = '$owner_uid'");
-
-               $salt = db_fetch_result($result, 0, "salt");
-               $login = db_fetch_result($result, 0, "login");
-
-               if (!$salt) {
-                       $password_hash1 = encrypt_password($password);
-                       $password_hash2 = encrypt_password($password, $login);
-
-                       $query = "SELECT id FROM ttrss_users WHERE
-                               id = '$owner_uid' AND (pwd_hash = '$password_hash1' OR
-                               pwd_hash = '$password_hash2')";
-
-               } else {
-                       $password_hash = encrypt_password($password, $salt, true);
-
-                       $query = "SELECT id FROM ttrss_users WHERE
-                               id = '$owner_uid' AND pwd_hash = '$password_hash'";
-               }
-
-               $result = db_query($this->link, $query);
-
-               return db_num_rows($result) != 0;
-       }
-
-       function change_password($owner_uid, $old_password, $new_password) {
-               $owner_uid = db_escape_string($owner_uid);
-
-               if ($this->check_password($owner_uid, $old_password)) {
-
-                       $new_salt = substr(bin2hex(get_random_bytes(125)), 0, 250);
-                       $new_password_hash = encrypt_password($new_password, $new_salt, true);
-
-                       db_query($this->link, "UPDATE ttrss_users SET
-                               pwd_hash = '$new_password_hash', salt = '$new_salt', otp_enabled = false
-                                       WHERE id = '$owner_uid'");
-
-                       $_SESSION["pwd_hash"] = $new_password_hash;
-
-                       return __("Password has been changed.");
-               } else {
-                       return "ERROR: ".__('Old password is incorrect.');
-               }
-       }
-}
-?>
diff --git a/plugins/auth_internal/init.php b/plugins/auth_internal/init.php
new file mode 100644 (file)
index 0000000..cf6c137
--- /dev/null
@@ -0,0 +1,191 @@
+<?php
+class Auth_Internal extends Plugin implements IAuthModule {
+
+       private $link;
+       private $host;
+
+       function about() {
+               return array(1.0,
+                       "Authenticates against internal tt-rss database",
+                       "fox",
+                       true);
+       }
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_hook($host::HOOK_AUTH_USER, $this);
+       }
+
+       function authenticate($login, $password) {
+
+               $pwd_hash1 = encrypt_password($password);
+               $pwd_hash2 = encrypt_password($password, $login);
+               $login = db_escape_string($login);
+               $otp = db_escape_string($_REQUEST["otp"]);
+
+               if (get_schema_version($this->link) > 96) {
+                       if (!defined('AUTH_DISABLE_OTP') || !AUTH_DISABLE_OTP) {
+                               $result = db_query($this->link, "SELECT otp_enabled,salt FROM ttrss_users WHERE
+                                       login = '$login'");
+
+                               if (db_num_rows($result) > 0) {
+                                       require_once "lib/otphp/vendor/base32.php";
+                                       require_once "lib/otphp/lib/otp.php";
+                                       require_once "lib/otphp/lib/totp.php";
+
+                                       $base32 = new Base32();
+
+                                       $otp_enabled = sql_bool_to_bool(db_fetch_result($result, 0, "otp_enabled"));
+                                       $secret = $base32->encode(sha1(db_fetch_result($result, 0, "salt")));
+
+                                       $topt = new \OTPHP\TOTP($secret);
+                                       $otp_check = $topt->now();
+
+                                       if ($otp_enabled) {
+                                               if ($otp) {
+                                                       if ($otp != $otp_check) {
+                                                               return false;
+                                                       }
+                                               } else {
+                                                       $return = urlencode($_REQUEST["return"]);
+                                                       ?><html>
+                                                               <head><title>Tiny Tiny RSS</title></head>
+                                                       <body>
+                                                       <form action="public.php?return=<?php echo $return ?>"
+                                                                       method="POST">
+                                                               <input type="hidden" name="op" value="login">
+                                                               <input type="hidden" name="login" value="<?php echo htmlspecialchars($login) ?>">
+                                                               <input type="hidden" name="password" value="<?php echo htmlspecialchars($password) ?>">
+
+                                                               <label><?php echo __("Please enter your one time password:") ?></label>
+                                                               <input type="password" size="6" name="otp"/>
+                                                               <input type="submit" value="Continue"/>
+                                                       </form>
+                                                       <script type="text/javascript">
+                                                               document.forms[0].otp.focus();
+                                                       </script>
+                                                       <?php
+                                                       exit;
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               if (get_schema_version($this->link) > 87) {
+
+                       $result = db_query($this->link, "SELECT salt FROM ttrss_users WHERE
+                               login = '$login'");
+
+                       if (db_num_rows($result) != 1) {
+                               return false;
+                       }
+
+                       $salt = db_fetch_result($result, 0, "salt");
+
+                       if ($salt == "") {
+
+                               $query = "SELECT id
+                   FROM ttrss_users WHERE
+                                       login = '$login' AND (pwd_hash = '$pwd_hash1' OR
+                                       pwd_hash = '$pwd_hash2')";
+
+                               // verify and upgrade password to new salt base
+
+                               $result = db_query($this->link, $query);
+
+                               if (db_num_rows($result) == 1) {
+                                       // upgrade password to MODE2
+
+                                       $salt = substr(bin2hex(get_random_bytes(125)), 0, 250);
+                                       $pwd_hash = encrypt_password($password, $salt, true);
+
+                                       db_query($this->link, "UPDATE ttrss_users SET
+                                               pwd_hash = '$pwd_hash', salt = '$salt' WHERE login = '$login'");
+
+                                       $query = "SELECT id
+                           FROM ttrss_users WHERE
+                                               login = '$login' AND pwd_hash = '$pwd_hash'";
+
+                               } else {
+                                       return false;
+                               }
+
+                       } else {
+
+                               $pwd_hash = encrypt_password($password, $salt, true);
+
+                               $query = "SELECT id
+                        FROM ttrss_users WHERE
+                                       login = '$login' AND pwd_hash = '$pwd_hash'";
+
+                       }
+
+               } else {
+                       $query = "SELECT id
+                FROM ttrss_users WHERE
+                               login = '$login' AND (pwd_hash = '$pwd_hash1' OR
+                                       pwd_hash = '$pwd_hash2')";
+               }
+
+               $result = db_query($this->link, $query);
+
+               if (db_num_rows($result) == 1) {
+                       return db_fetch_result($result, 0, "id");
+               }
+
+               return false;
+       }
+
+       function check_password($owner_uid, $password) {
+               $owner_uid = db_escape_string($owner_uid);
+
+               $result = db_query($this->link, "SELECT salt,login FROM ttrss_users WHERE
+                       id = '$owner_uid'");
+
+               $salt = db_fetch_result($result, 0, "salt");
+               $login = db_fetch_result($result, 0, "login");
+
+               if (!$salt) {
+                       $password_hash1 = encrypt_password($password);
+                       $password_hash2 = encrypt_password($password, $login);
+
+                       $query = "SELECT id FROM ttrss_users WHERE
+                               id = '$owner_uid' AND (pwd_hash = '$password_hash1' OR
+                               pwd_hash = '$password_hash2')";
+
+               } else {
+                       $password_hash = encrypt_password($password, $salt, true);
+
+                       $query = "SELECT id FROM ttrss_users WHERE
+                               id = '$owner_uid' AND pwd_hash = '$password_hash'";
+               }
+
+               $result = db_query($this->link, $query);
+
+               return db_num_rows($result) != 0;
+       }
+
+       function change_password($owner_uid, $old_password, $new_password) {
+               $owner_uid = db_escape_string($owner_uid);
+
+               if ($this->check_password($owner_uid, $old_password)) {
+
+                       $new_salt = substr(bin2hex(get_random_bytes(125)), 0, 250);
+                       $new_password_hash = encrypt_password($new_password, $new_salt, true);
+
+                       db_query($this->link, "UPDATE ttrss_users SET
+                               pwd_hash = '$new_password_hash', salt = '$new_salt', otp_enabled = false
+                                       WHERE id = '$owner_uid'");
+
+                       $_SESSION["pwd_hash"] = $new_password_hash;
+
+                       return __("Password has been changed.");
+               } else {
+                       return "ERROR: ".__('Old password is incorrect.');
+               }
+       }
+}
+?>
diff --git a/plugins/auth_remote/auth_remote.php b/plugins/auth_remote/auth_remote.php
deleted file mode 100644 (file)
index 65f188b..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-<?php
-class Auth_Remote extends Plugin implements IAuthModule {
-
-       private $link;
-       private $host;
-       private $base;
-
-       function about() {
-               return array(1.0,
-                       "Authenticates against remote password (e.g. supplied by Apache)",
-                       "fox",
-                       true);
-       }
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-               $this->base = new Auth_Base($this->link);
-
-               $host->add_hook($host::HOOK_AUTH_USER, $this);
-       }
-
-       function get_login_by_ssl_certificate() {
-               $cert_serial = db_escape_string(get_ssl_certificate_id());
-
-               if ($cert_serial) {
-                       $result = db_query($this->link, "SELECT login FROM ttrss_user_prefs, ttrss_users
-                               WHERE pref_name = 'SSL_CERT_SERIAL' AND value = '$cert_serial' AND
-                               owner_uid = ttrss_users.id");
-
-                       if (db_num_rows($result) != 0) {
-                               return db_escape_string(db_fetch_result($result, 0, "login"));
-                       }
-               }
-
-               return "";
-       }
-
-
-       function authenticate($login, $password) {
-               $try_login = db_escape_string($_SERVER["REMOTE_USER"]);
-
-               if (!$try_login) $try_login = $this->get_login_by_ssl_certificate();
-#              if (!$try_login) $try_login = "test_qqq";
-
-               if ($try_login) {
-                       $user_id = $this->base->auto_create_user($try_login);
-
-                       if ($user_id) {
-                               $_SESSION["fake_login"] = $try_login;
-                               $_SESSION["fake_password"] = "******";
-                               $_SESSION["hide_hello"] = true;
-                               $_SESSION["hide_logout"] = true;
-
-                               // LemonLDAP can send user informations via HTTP HEADER
-                               if (defined('AUTH_AUTO_CREATE') && AUTH_AUTO_CREATE){
-                                       // update user name
-                                       $fullname = $_SERVER['HTTP_USER_NAME'] ? $_SERVER['HTTP_USER_NAME'] : $_SERVER['AUTHENTICATE_CN'];
-                                       if ($fullname){
-                                               $fullname = db_escape_string($fullname);
-                                               db_query($this->link, "UPDATE ttrss_users SET full_name = '$fullname' WHERE id = " .
-                                                       $user_id);
-                                       }
-                                       // update user mail
-                                       $email = $_SERVER['HTTP_USER_MAIL'] ? $_SERVER['HTTP_USER_MAIL'] : $_SERVER['AUTHENTICATE_MAIL'];
-                                       if ($email){
-                                               $email = db_escape_string($email);
-                                               db_query($this->link, "UPDATE ttrss_users SET email = '$email' WHERE id = " .
-                                                       $user_id);
-                                       }
-                               }
-
-                               return $user_id;
-                       }
-               }
-
-               return false;
-       }
-}
-
-?>
diff --git a/plugins/auth_remote/init.php b/plugins/auth_remote/init.php
new file mode 100644 (file)
index 0000000..65f188b
--- /dev/null
@@ -0,0 +1,81 @@
+<?php
+class Auth_Remote extends Plugin implements IAuthModule {
+
+       private $link;
+       private $host;
+       private $base;
+
+       function about() {
+               return array(1.0,
+                       "Authenticates against remote password (e.g. supplied by Apache)",
+                       "fox",
+                       true);
+       }
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+               $this->base = new Auth_Base($this->link);
+
+               $host->add_hook($host::HOOK_AUTH_USER, $this);
+       }
+
+       function get_login_by_ssl_certificate() {
+               $cert_serial = db_escape_string(get_ssl_certificate_id());
+
+               if ($cert_serial) {
+                       $result = db_query($this->link, "SELECT login FROM ttrss_user_prefs, ttrss_users
+                               WHERE pref_name = 'SSL_CERT_SERIAL' AND value = '$cert_serial' AND
+                               owner_uid = ttrss_users.id");
+
+                       if (db_num_rows($result) != 0) {
+                               return db_escape_string(db_fetch_result($result, 0, "login"));
+                       }
+               }
+
+               return "";
+       }
+
+
+       function authenticate($login, $password) {
+               $try_login = db_escape_string($_SERVER["REMOTE_USER"]);
+
+               if (!$try_login) $try_login = $this->get_login_by_ssl_certificate();
+#              if (!$try_login) $try_login = "test_qqq";
+
+               if ($try_login) {
+                       $user_id = $this->base->auto_create_user($try_login);
+
+                       if ($user_id) {
+                               $_SESSION["fake_login"] = $try_login;
+                               $_SESSION["fake_password"] = "******";
+                               $_SESSION["hide_hello"] = true;
+                               $_SESSION["hide_logout"] = true;
+
+                               // LemonLDAP can send user informations via HTTP HEADER
+                               if (defined('AUTH_AUTO_CREATE') && AUTH_AUTO_CREATE){
+                                       // update user name
+                                       $fullname = $_SERVER['HTTP_USER_NAME'] ? $_SERVER['HTTP_USER_NAME'] : $_SERVER['AUTHENTICATE_CN'];
+                                       if ($fullname){
+                                               $fullname = db_escape_string($fullname);
+                                               db_query($this->link, "UPDATE ttrss_users SET full_name = '$fullname' WHERE id = " .
+                                                       $user_id);
+                                       }
+                                       // update user mail
+                                       $email = $_SERVER['HTTP_USER_MAIL'] ? $_SERVER['HTTP_USER_MAIL'] : $_SERVER['AUTHENTICATE_MAIL'];
+                                       if ($email){
+                                               $email = db_escape_string($email);
+                                               db_query($this->link, "UPDATE ttrss_users SET email = '$email' WHERE id = " .
+                                                       $user_id);
+                                       }
+                               }
+
+                               return $user_id;
+                       }
+               }
+
+               return false;
+       }
+}
+
+?>
diff --git a/plugins/digest/digest.php b/plugins/digest/digest.php
deleted file mode 100644 (file)
index 503ae5b..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-<?php
-class Digest extends Plugin implements IHandler {
-
-       private $link;
-       private $host;
-
-       function about() {
-               return array(1.0,
-                       "Digest mode for tt-rss (tablet friendly UI)",
-                       "fox",
-                       true);
-       }
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-
-               $host->add_handler("digest", "*", $this);
-       }
-
-       function index() {
-               header("Content-type: text/html; charset=utf-8");
-
-               login_sequence($this->link);
-
-               global $link;
-               $link = $this->link;
-
-               require_once dirname(__FILE__) . "/digest_body.php";
-       }
-
-       /* function get_js() {
-               return file_get_contents(dirname(__FILE__) . "/digest.js");
-       } */
-
-       function csrf_ignore($method) {
-               return in_array($method, array("index"));
-       }
-
-       function before($method) {
-               return true;
-       }
-
-       function after() {
-
-       }
-
-       function digestgetcontents() {
-               $article_id = db_escape_string($_REQUEST['article_id']);
-
-               $result = db_query($this->link, "SELECT content,title,link,marked,published
-                       FROM ttrss_entries, ttrss_user_entries
-                       WHERE id = '$article_id' AND ref_id = id AND owner_uid = ".$_SESSION['uid']);
-
-               $content = sanitize($this->link, db_fetch_result($result, 0, "content"));
-               $title = strip_tags(db_fetch_result($result, 0, "title"));
-               $article_url = htmlspecialchars(db_fetch_result($result, 0, "link"));
-               $marked = sql_bool_to_bool(db_fetch_result($result, 0, "marked"));
-               $published = sql_bool_to_bool(db_fetch_result($result, 0, "published"));
-
-               print json_encode(array("article" =>
-                       array("id" => $article_id, "url" => $article_url,
-                               "tags" => get_article_tags($this->link, $article_id),
-                               "marked" => $marked, "published" => $published,
-                               "title" => $title, "content" => $content)));
-       }
-
-       function digestupdate() {
-               $feed_id = db_escape_string($_REQUEST['feed_id']);
-               $offset = db_escape_string($_REQUEST['offset']);
-               $seq = db_escape_string($_REQUEST['seq']);
-
-               if (!$feed_id) $feed_id = -4;
-               if (!$offset) $offset = 0;
-
-               $reply = array();
-
-               $reply['seq'] = $seq;
-
-               $headlines = api_get_headlines($this->link, $feed_id, 30, $offset,
-                               '', ($feed_id == -4), true, false, "unread", "updated DESC", 0, 0);
-
-               $reply['headlines'] = array();
-               $reply['headlines']['title'] = getFeedTitle($this->link, $feed_id);
-               $reply['headlines']['content'] = $headlines;
-
-               print json_encode($reply);
-       }
-
-       function digestinit() {
-               $tmp_feeds = api_get_feeds($this->link, -4, true, false, 0);
-
-               $feeds = array();
-
-               foreach ($tmp_feeds as $f) {
-                       if ($f['id'] > 0 || $f['id'] == -4) array_push($feeds, $f);
-               }
-
-               print json_encode(array("feeds" => $feeds));
-       }
-
-}
-?>
diff --git a/plugins/digest/init.php b/plugins/digest/init.php
new file mode 100644 (file)
index 0000000..503ae5b
--- /dev/null
@@ -0,0 +1,103 @@
+<?php
+class Digest extends Plugin implements IHandler {
+
+       private $link;
+       private $host;
+
+       function about() {
+               return array(1.0,
+                       "Digest mode for tt-rss (tablet friendly UI)",
+                       "fox",
+                       true);
+       }
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_handler("digest", "*", $this);
+       }
+
+       function index() {
+               header("Content-type: text/html; charset=utf-8");
+
+               login_sequence($this->link);
+
+               global $link;
+               $link = $this->link;
+
+               require_once dirname(__FILE__) . "/digest_body.php";
+       }
+
+       /* function get_js() {
+               return file_get_contents(dirname(__FILE__) . "/digest.js");
+       } */
+
+       function csrf_ignore($method) {
+               return in_array($method, array("index"));
+       }
+
+       function before($method) {
+               return true;
+       }
+
+       function after() {
+
+       }
+
+       function digestgetcontents() {
+               $article_id = db_escape_string($_REQUEST['article_id']);
+
+               $result = db_query($this->link, "SELECT content,title,link,marked,published
+                       FROM ttrss_entries, ttrss_user_entries
+                       WHERE id = '$article_id' AND ref_id = id AND owner_uid = ".$_SESSION['uid']);
+
+               $content = sanitize($this->link, db_fetch_result($result, 0, "content"));
+               $title = strip_tags(db_fetch_result($result, 0, "title"));
+               $article_url = htmlspecialchars(db_fetch_result($result, 0, "link"));
+               $marked = sql_bool_to_bool(db_fetch_result($result, 0, "marked"));
+               $published = sql_bool_to_bool(db_fetch_result($result, 0, "published"));
+
+               print json_encode(array("article" =>
+                       array("id" => $article_id, "url" => $article_url,
+                               "tags" => get_article_tags($this->link, $article_id),
+                               "marked" => $marked, "published" => $published,
+                               "title" => $title, "content" => $content)));
+       }
+
+       function digestupdate() {
+               $feed_id = db_escape_string($_REQUEST['feed_id']);
+               $offset = db_escape_string($_REQUEST['offset']);
+               $seq = db_escape_string($_REQUEST['seq']);
+
+               if (!$feed_id) $feed_id = -4;
+               if (!$offset) $offset = 0;
+
+               $reply = array();
+
+               $reply['seq'] = $seq;
+
+               $headlines = api_get_headlines($this->link, $feed_id, 30, $offset,
+                               '', ($feed_id == -4), true, false, "unread", "updated DESC", 0, 0);
+
+               $reply['headlines'] = array();
+               $reply['headlines']['title'] = getFeedTitle($this->link, $feed_id);
+               $reply['headlines']['content'] = $headlines;
+
+               print json_encode($reply);
+       }
+
+       function digestinit() {
+               $tmp_feeds = api_get_feeds($this->link, -4, true, false, 0);
+
+               $feeds = array();
+
+               foreach ($tmp_feeds as $f) {
+                       if ($f['id'] > 0 || $f['id'] == -4) array_push($feeds, $f);
+               }
+
+               print json_encode(array("feeds" => $feeds));
+       }
+
+}
+?>
diff --git a/plugins/example/example.php b/plugins/example/example.php
deleted file mode 100644 (file)
index f3788ae..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-<?php
-class Example extends Plugin {
-
-       // Demonstrates how to add a separate panel to the preferences screen and inject Javascript/save data using Dojo forms.
-
-       private $link;
-       private $host;
-
-       function about() {
-               return array(1.0,
-                       "Example plugin #1",
-                       "fox",
-                       true);
-       }
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-
-               $host->add_hook($host::HOOK_PREFS_TAB, $this);
-       }
-
-       function save() {
-               $example_value = db_escape_string($_POST["example_value"]);
-
-               $this->host->set($this, "example", $example_value);
-
-               echo "Value set to $example_value";
-       }
-
-       function get_prefs_js() {
-               return file_get_contents(dirname(__FILE__) . "/example.js");
-       }
-
-       function hook_prefs_tab($args) {
-               if ($args != "prefPrefs") return;
-
-               print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__("Example Pane")."\">";
-
-               print "<br/>";
-
-//             print_r($this->host->set($this, "example", rand(0,100)));
-//             print_r($this->host->get_all($this));
-
-               $value = $this->host->get($this, "example");
-
-               print "<form dojoType=\"dijit.form.Form\">";
-
-               print "<script type=\"dojo/method\" event=\"onSubmit\" args=\"evt\">
-                       evt.preventDefault();
-                       if (this.validate()) {
-                               console.log(dojo.objectToQuery(this.getValues()));
-                               new Ajax.Request('backend.php', {
-                                       parameters: dojo.objectToQuery(this.getValues()),
-                                       onComplete: function(transport) {
-                                               notify_info(transport.responseText);
-                                       }
-                               });
-                               //this.reset();
-                       }
-                       </script>";
-
-                       print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pluginhandler\">";
-                       print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"save\">";
-                       print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"plugin\" value=\"example\">";
-
-               print "<table width=\"100%\" class=\"prefPrefsList\">";
-
-                       print "<tr><td width=\"40%\">".__("Sample value")."</td>";
-                       print "<td class=\"prefValue\"><input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\" name=\"example_value\" value=\"$value\"></td></tr>";
-
-                       print "</table>";
-
-                       print "<p><button dojoType=\"dijit.form.Button\" type=\"submit\">".
-                               __("Set value")."</button>";
-
-                       print "</form>";
-
-               print "</div>"; #pane
-       }
-}
-?>
diff --git a/plugins/example/init.php b/plugins/example/init.php
new file mode 100644 (file)
index 0000000..f3788ae
--- /dev/null
@@ -0,0 +1,82 @@
+<?php
+class Example extends Plugin {
+
+       // Demonstrates how to add a separate panel to the preferences screen and inject Javascript/save data using Dojo forms.
+
+       private $link;
+       private $host;
+
+       function about() {
+               return array(1.0,
+                       "Example plugin #1",
+                       "fox",
+                       true);
+       }
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_hook($host::HOOK_PREFS_TAB, $this);
+       }
+
+       function save() {
+               $example_value = db_escape_string($_POST["example_value"]);
+
+               $this->host->set($this, "example", $example_value);
+
+               echo "Value set to $example_value";
+       }
+
+       function get_prefs_js() {
+               return file_get_contents(dirname(__FILE__) . "/example.js");
+       }
+
+       function hook_prefs_tab($args) {
+               if ($args != "prefPrefs") return;
+
+               print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__("Example Pane")."\">";
+
+               print "<br/>";
+
+//             print_r($this->host->set($this, "example", rand(0,100)));
+//             print_r($this->host->get_all($this));
+
+               $value = $this->host->get($this, "example");
+
+               print "<form dojoType=\"dijit.form.Form\">";
+
+               print "<script type=\"dojo/method\" event=\"onSubmit\" args=\"evt\">
+                       evt.preventDefault();
+                       if (this.validate()) {
+                               console.log(dojo.objectToQuery(this.getValues()));
+                               new Ajax.Request('backend.php', {
+                                       parameters: dojo.objectToQuery(this.getValues()),
+                                       onComplete: function(transport) {
+                                               notify_info(transport.responseText);
+                                       }
+                               });
+                               //this.reset();
+                       }
+                       </script>";
+
+                       print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pluginhandler\">";
+                       print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"save\">";
+                       print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"plugin\" value=\"example\">";
+
+               print "<table width=\"100%\" class=\"prefPrefsList\">";
+
+                       print "<tr><td width=\"40%\">".__("Sample value")."</td>";
+                       print "<td class=\"prefValue\"><input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\" name=\"example_value\" value=\"$value\"></td></tr>";
+
+                       print "</table>";
+
+                       print "<p><button dojoType=\"dijit.form.Button\" type=\"submit\">".
+                               __("Set value")."</button>";
+
+                       print "</form>";
+
+               print "</div>"; #pane
+       }
+}
+?>
diff --git a/plugins/example_feed/example_feed.php b/plugins/example_feed/example_feed.php
deleted file mode 100644 (file)
index af14d3f..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-class Example_Feed extends Plugin {
-
-       // Demonstrates how to query data from the parsed feed object (SimplePie)
-       // don't enable unless debugging feed through f D hotkey or manually.
-
-       private $link;
-       private $host;
-
-       function about() {
-               return array(1.0,
-                       "Example feed plugin",
-                       "fox",
-                       true);
-       }
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-
-               $host->add_hook($host::HOOK_FEED_PARSED, $this);
-       }
-
-       function hook_feed_parsed($feed) {
-               _debug("I'm a little feed short and stout, here's my title: " . $feed->get_title());
-               _debug("... here's my link element: " . $feed->get_link());
-       }
-}
-?>
diff --git a/plugins/example_feed/init.php b/plugins/example_feed/init.php
new file mode 100644 (file)
index 0000000..af14d3f
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+class Example_Feed extends Plugin {
+
+       // Demonstrates how to query data from the parsed feed object (SimplePie)
+       // don't enable unless debugging feed through f D hotkey or manually.
+
+       private $link;
+       private $host;
+
+       function about() {
+               return array(1.0,
+                       "Example feed plugin",
+                       "fox",
+                       true);
+       }
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_hook($host::HOOK_FEED_PARSED, $this);
+       }
+
+       function hook_feed_parsed($feed) {
+               _debug("I'm a little feed short and stout, here's my title: " . $feed->get_title());
+               _debug("... here's my link element: " . $feed->get_link());
+       }
+}
+?>
diff --git a/plugins/example_routing/example_routing.php b/plugins/example_routing/example_routing.php
deleted file mode 100644 (file)
index 31c5b6f..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-class Example_Routing extends Plugin implements IHandler {
-
-       // Demonstrates adding a custom handler and method:
-       // backend.php?op=test&method=example
-       // and masking a system builtin public method:
-       // public.php?op=getUnread
-
-       // Plugin class must implelement IHandler interface and has
-       // a public method of same name as being registered.
-       //
-       // Any system method may be masked by plugins. You can mask
-       // entire handler by supplying "*" instead of a method name.
-
-       private $link;
-       private $host;
-
-       function about() {
-               return array(1.0,
-                       "Example routing plugin",
-                       "fox",
-                       true);
-       }
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-
-               $host->add_handler("test", "example", $this);
-               $host->add_handler("public", "getunread", $this);
-       }
-
-       function getunread() {
-               print rand(0,100); # yeah right
-       }
-
-       function example() {
-               print "example method called";
-       }
-
-       function csrf_ignore($method) {
-               return true;
-       }
-
-       function before($method) {
-               return true;
-       }
-
-       function after() {
-               return true;
-       }
-
-}
-?>
diff --git a/plugins/example_routing/init.php b/plugins/example_routing/init.php
new file mode 100644 (file)
index 0000000..31c5b6f
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+class Example_Routing extends Plugin implements IHandler {
+
+       // Demonstrates adding a custom handler and method:
+       // backend.php?op=test&method=example
+       // and masking a system builtin public method:
+       // public.php?op=getUnread
+
+       // Plugin class must implelement IHandler interface and has
+       // a public method of same name as being registered.
+       //
+       // Any system method may be masked by plugins. You can mask
+       // entire handler by supplying "*" instead of a method name.
+
+       private $link;
+       private $host;
+
+       function about() {
+               return array(1.0,
+                       "Example routing plugin",
+                       "fox",
+                       true);
+       }
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_handler("test", "example", $this);
+               $host->add_handler("public", "getunread", $this);
+       }
+
+       function getunread() {
+               print rand(0,100); # yeah right
+       }
+
+       function example() {
+               print "example method called";
+       }
+
+       function csrf_ignore($method) {
+               return true;
+       }
+
+       function before($method) {
+               return true;
+       }
+
+       function after() {
+               return true;
+       }
+
+}
+?>
diff --git a/plugins/flattr/flattr.php b/plugins/flattr/flattr.php
deleted file mode 100644 (file)
index 86f21fa..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-class Flattr extends Plugin {
-       private $link;
-       private $host;
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-
-               $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
-       }
-
-       function about() {
-               return array(1.0,
-                       "Share articles on Flattr",
-                       "Nic Honing");
-       }
-
-  function hook_article_button($line) {
-
-       $article_id = $line["id"];
-
-    $result = db_query($this->link, "SELECT link
-      FROM ttrss_entries, ttrss_user_entries
-      WHERE id = '$article_id' AND ref_id = id AND owner_uid = " .$_SESSION['uid']);
-
-    if (db_num_rows($result) != 0) {
-      $article_link = db_fetch_result($result, 0, 'link');
-    }
-
-    $response = null;
-    if ($article_link) {
-      $encoded = urlencode($article_link);
-      $r = file_get_contents("https://api.flattr.com/rest/v2/things/lookup/?url=$encoded");
-      $response = json_decode($r, true);
-    }
-
-    $rv = null;
-    if ($response and array_key_exists('link', $response)) {
-      $rv = "<a id='flattr' href='" . $response['link'] . "'>
-        <img src=\"".theme_image($this->link, 'plugins/flattr/flattr.png')."\"
-        class='tagsPic' style=\"cursor : pointer\"
-        title='".__('Flattr article')."'>
-        </a>";
-    } else {
-      $rv = "";
-    }
-
-    return $rv;
-  }
-}
-?>
diff --git a/plugins/flattr/init.php b/plugins/flattr/init.php
new file mode 100644 (file)
index 0000000..86f21fa
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+class Flattr extends Plugin {
+       private $link;
+       private $host;
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
+       }
+
+       function about() {
+               return array(1.0,
+                       "Share articles on Flattr",
+                       "Nic Honing");
+       }
+
+  function hook_article_button($line) {
+
+       $article_id = $line["id"];
+
+    $result = db_query($this->link, "SELECT link
+      FROM ttrss_entries, ttrss_user_entries
+      WHERE id = '$article_id' AND ref_id = id AND owner_uid = " .$_SESSION['uid']);
+
+    if (db_num_rows($result) != 0) {
+      $article_link = db_fetch_result($result, 0, 'link');
+    }
+
+    $response = null;
+    if ($article_link) {
+      $encoded = urlencode($article_link);
+      $r = file_get_contents("https://api.flattr.com/rest/v2/things/lookup/?url=$encoded");
+      $response = json_decode($r, true);
+    }
+
+    $rv = null;
+    if ($response and array_key_exists('link', $response)) {
+      $rv = "<a id='flattr' href='" . $response['link'] . "'>
+        <img src=\"".theme_image($this->link, 'plugins/flattr/flattr.png')."\"
+        class='tagsPic' style=\"cursor : pointer\"
+        title='".__('Flattr article')."'>
+        </a>";
+    } else {
+      $rv = "";
+    }
+
+    return $rv;
+  }
+}
+?>
diff --git a/plugins/googleplus/googleplus.php b/plugins/googleplus/googleplus.php
deleted file mode 100644 (file)
index 3d6c608..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-class GooglePlus extends Plugin {
-       private $link;
-       private $host;
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-
-               $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
-       }
-
-       function about() {
-               return array(1.0,
-                       "Share article on Google+",
-                       "homolibere");
-       }
-
-       function get_js() {
-               return file_get_contents(dirname(__FILE__) . "/googleplus.js");
-       }
-
-       function hook_article_button($line) {
-               $article_id = $line["id"];
-
-               $rv = "<img src=\"".theme_image($this->link, 'plugins/googleplus/googleplus.png')."\"
-                       class='tagsPic' style=\"cursor : pointer\"
-                       onclick=\"shareArticleToGooglePlus($article_id)\"
-                       title='".__('Share on Google+')."'>";
-
-               return $rv;
-       }
-
-       function getInfo() {
-               $id = db_escape_string($_REQUEST['id']);
-
-               $result = db_query($this->link, "SELECT title, link
-                               FROM ttrss_entries, ttrss_user_entries
-                               WHERE id = '$id' AND ref_id = id AND owner_uid = " .$_SESSION['uid']);
-
-               if (db_num_rows($result) != 0) {
-                       $title = truncate_string(strip_tags(db_fetch_result($result, 0, 'title')),
-                               100, '...');
-                       $article_link = db_fetch_result($result, 0, 'link');
-               }
-
-               print json_encode(array("title" => $title, "link" => $article_link,
-                               "id" => $id));
-       }
-
-
-}
-?>
diff --git a/plugins/googleplus/init.php b/plugins/googleplus/init.php
new file mode 100644 (file)
index 0000000..3d6c608
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+class GooglePlus extends Plugin {
+       private $link;
+       private $host;
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
+       }
+
+       function about() {
+               return array(1.0,
+                       "Share article on Google+",
+                       "homolibere");
+       }
+
+       function get_js() {
+               return file_get_contents(dirname(__FILE__) . "/googleplus.js");
+       }
+
+       function hook_article_button($line) {
+               $article_id = $line["id"];
+
+               $rv = "<img src=\"".theme_image($this->link, 'plugins/googleplus/googleplus.png')."\"
+                       class='tagsPic' style=\"cursor : pointer\"
+                       onclick=\"shareArticleToGooglePlus($article_id)\"
+                       title='".__('Share on Google+')."'>";
+
+               return $rv;
+       }
+
+       function getInfo() {
+               $id = db_escape_string($_REQUEST['id']);
+
+               $result = db_query($this->link, "SELECT title, link
+                               FROM ttrss_entries, ttrss_user_entries
+                               WHERE id = '$id' AND ref_id = id AND owner_uid = " .$_SESSION['uid']);
+
+               if (db_num_rows($result) != 0) {
+                       $title = truncate_string(strip_tags(db_fetch_result($result, 0, 'title')),
+                               100, '...');
+                       $article_link = db_fetch_result($result, 0, 'link');
+               }
+
+               print json_encode(array("title" => $title, "link" => $article_link,
+                               "id" => $id));
+       }
+
+
+}
+?>
diff --git a/plugins/identica/identica.php b/plugins/identica/identica.php
deleted file mode 100644 (file)
index c260334..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-class Identica extends Plugin {
-       private $link;
-       private $host;
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-
-               $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
-       }
-
-       function about() {
-               return array(1.0,
-                       "Share articles on Identi.ca",
-                       "fox");
-       }
-
-       function get_js() {
-               return file_get_contents(dirname(__FILE__) . "/identica.js");
-       }
-
-       function hook_article_button($line) {
-               $article_id = $line["id"];
-
-               $rv = "<img src=\"".theme_image($this->link, 'plugins/identica/identica.png')."\"
-                       class='tagsPic' style=\"cursor : pointer\"
-                       onclick=\"shareArticleToIdentica($article_id)\"
-                       title='".__('Share on identi.ca')."'>";
-
-               return $rv;
-       }
-
-       function getInfo() {
-               $id = db_escape_string($_REQUEST['id']);
-
-               $result = db_query($this->link, "SELECT title, link
-                               FROM ttrss_entries, ttrss_user_entries
-                               WHERE id = '$id' AND ref_id = id AND owner_uid = " .$_SESSION['uid']);
-
-               if (db_num_rows($result) != 0) {
-                       $title = truncate_string(strip_tags(db_fetch_result($result, 0, 'title')),
-                               100, '...');
-                       $article_link = db_fetch_result($result, 0, 'link');
-               }
-
-               print json_encode(array("title" => $title, "link" => $article_link,
-                               "id" => $id));
-       }
-
-
-}
-?>
diff --git a/plugins/identica/init.php b/plugins/identica/init.php
new file mode 100644 (file)
index 0000000..c260334
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+class Identica extends Plugin {
+       private $link;
+       private $host;
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
+       }
+
+       function about() {
+               return array(1.0,
+                       "Share articles on Identi.ca",
+                       "fox");
+       }
+
+       function get_js() {
+               return file_get_contents(dirname(__FILE__) . "/identica.js");
+       }
+
+       function hook_article_button($line) {
+               $article_id = $line["id"];
+
+               $rv = "<img src=\"".theme_image($this->link, 'plugins/identica/identica.png')."\"
+                       class='tagsPic' style=\"cursor : pointer\"
+                       onclick=\"shareArticleToIdentica($article_id)\"
+                       title='".__('Share on identi.ca')."'>";
+
+               return $rv;
+       }
+
+       function getInfo() {
+               $id = db_escape_string($_REQUEST['id']);
+
+               $result = db_query($this->link, "SELECT title, link
+                               FROM ttrss_entries, ttrss_user_entries
+                               WHERE id = '$id' AND ref_id = id AND owner_uid = " .$_SESSION['uid']);
+
+               if (db_num_rows($result) != 0) {
+                       $title = truncate_string(strip_tags(db_fetch_result($result, 0, 'title')),
+                               100, '...');
+                       $article_link = db_fetch_result($result, 0, 'link');
+               }
+
+               print json_encode(array("title" => $title, "link" => $article_link,
+                               "id" => $id));
+       }
+
+
+}
+?>
diff --git a/plugins/import_export/import_export.php b/plugins/import_export/import_export.php
deleted file mode 100644 (file)
index de21dbf..0000000
+++ /dev/null
@@ -1,439 +0,0 @@
-<?php
-class Import_Export extends Plugin implements IHandler {
-
-       private $link;
-       private $host;
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-
-               $host->add_hook($host::HOOK_PREFS_TAB, $this);
-               $host->add_command("xml-import", "USER FILE: import articles from XML", $this);
-       }
-
-       function about() {
-               return array(1.0,
-                       "Imports and exports user data using neutral XML format",
-                       "fox");
-       }
-
-       function xml_import($args) {
-               array_shift($args);
-
-               $username = $args[count($args) - 2];
-               $filename = $args[count($args) - 1];
-
-               if (!$username) {
-                       print "error: please specify username.\n";
-                       return;
-               }
-
-               if (!is_file($filename)) {
-                       print "error: input filename ($filename) doesn't exist.\n";
-                       return;
-               }
-
-               _debug("importing $filename for user $username...\n");
-
-               $result = db_query($this->link, "SELECT id FROM ttrss_users WHERE login = '$username'");
-
-               if (db_num_rows($result) == 0) {
-                       print "error: could not find user $username.\n";
-                       return;
-               }
-
-               $owner_uid = db_fetch_result($result, 0, "id");
-
-               $this->perform_data_import($this->link, $filename, $owner_uid);
-       }
-
-       function save() {
-               $example_value = db_escape_string($_POST["example_value"]);
-
-               echo "Value set to $example_value (not really)";
-       }
-
-       function get_prefs_js() {
-               return file_get_contents(dirname(__FILE__) . "/import_export.js");
-       }
-
-       function hook_prefs_tab($args) {
-               if ($args != "prefFeeds") return;
-
-               print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__('Import and export')."\">";
-
-               print "<h3>" . __("Article archive") . "</h3>";
-
-               print "<p>" . __("You can export and import your Starred and Archived articles for safekeeping or when migrating between tt-rss instances.") . "</p>";
-
-               print "<button dojoType=\"dijit.form.Button\" onclick=\"return exportData()\">".
-                       __('Export my data')."</button> ";
-
-               print "<hr>";
-
-               print "<iframe id=\"data_upload_iframe\"
-                       name=\"data_upload_iframe\" onload=\"dataImportComplete(this)\"
-                       style=\"width: 400px; height: 100px; display: none;\"></iframe>";
-
-               print "<form name=\"import_form\" style='display : block' target=\"data_upload_iframe\"
-                       enctype=\"multipart/form-data\" method=\"POST\"
-                       action=\"backend.php\">
-                       <input id=\"export_file\" name=\"export_file\" type=\"file\">&nbsp;
-                       <input type=\"hidden\" name=\"op\" value=\"pluginhandler\">
-                       <input type=\"hidden\" name=\"plugin\" value=\"import_export\">
-                       <input type=\"hidden\" name=\"method\" value=\"dataimport\">
-                       <button dojoType=\"dijit.form.Button\" onclick=\"return importData();\" type=\"submit\">" .
-                       __('Import') . "</button>";
-
-
-               print "</div>"; # pane
-       }
-
-       function csrf_ignore($method) {
-               return in_array($method, array("exportget"));
-       }
-
-       function before($method) {
-               return $_SESSION["uid"] != false;
-       }
-
-       function after() {
-               return true;
-       }
-
-       function exportget() {
-               $exportname = CACHE_DIR . "/export/" .
-                       sha1($_SESSION['uid'] . $_SESSION['login']) . ".xml";
-
-               if (file_exists($exportname)) {
-                       header("Content-type: text/xml");
-
-                       if (function_exists('gzencode')) {
-                               header("Content-Disposition: attachment; filename=TinyTinyRSS_exported.xml.gz");
-                               echo gzencode(file_get_contents($exportname));
-                       } else {
-                               header("Content-Disposition: attachment; filename=TinyTinyRSS_exported.xml");
-                               echo file_get_contents($exportname);
-                       }
-               } else {
-                       echo "File not found.";
-               }
-       }
-
-       function exportrun() {
-               $offset = (int) db_escape_string($_REQUEST['offset']);
-               $exported = 0;
-               $limit = 250;
-
-               if ($offset < 10000 && is_writable(CACHE_DIR . "/export")) {
-                       $result = db_query($this->link, "SELECT
-                                       ttrss_entries.guid,
-                                       ttrss_entries.title,
-                                       content,
-                                       marked,
-                                       published,
-                                       score,
-                                       note,
-                                       link,
-                                       tag_cache,
-                                       label_cache,
-                                       ttrss_feeds.title AS feed_title,
-                                       ttrss_feeds.feed_url AS feed_url,
-                                       ttrss_entries.updated
-                               FROM
-                                       ttrss_user_entries LEFT JOIN ttrss_feeds ON (ttrss_feeds.id = feed_id),
-                                       ttrss_entries
-                               WHERE
-                                       (marked = true OR feed_id IS NULL) AND
-                                       ref_id = ttrss_entries.id AND
-                                       ttrss_user_entries.owner_uid = " . $_SESSION['uid'] . "
-                               ORDER BY ttrss_entries.id LIMIT $limit OFFSET $offset");
-
-                       $exportname = sha1($_SESSION['uid'] . $_SESSION['login']);
-
-                       if ($offset == 0) {
-                               $fp = fopen(CACHE_DIR . "/export/$exportname.xml", "w");
-                               fputs($fp, "<articles schema-version=\"".SCHEMA_VERSION."\">");
-                       } else {
-                               $fp = fopen(CACHE_DIR . "/export/$exportname.xml", "a");
-                       }
-
-                       if ($fp) {
-
-                               while ($line = db_fetch_assoc($result)) {
-                                       fputs($fp, "<article>");
-
-                                       foreach ($line as $k => $v) {
-                                               fputs($fp, "<$k><![CDATA[$v]]></$k>");
-                                       }
-
-                                       fputs($fp, "</article>");
-                               }
-
-                               $exported = db_num_rows($result);
-
-                               if ($exported < $limit && $exported > 0) {
-                                       fputs($fp, "</articles>");
-                               }
-
-                               fclose($fp);
-                       }
-
-               }
-
-               print json_encode(array("exported" => $exported));
-       }
-
-       function perform_data_import($link, $filename, $owner_uid) {
-
-               $num_imported = 0;
-               $num_processed = 0;
-               $num_feeds_created = 0;
-
-               $doc = @DOMDocument::load($filename);
-
-               if (!$doc) {
-                       $contents = file_get_contents($filename);
-
-                       if ($contents) {
-                               $data = @gzuncompress($contents);
-                       }
-
-                       if (!$data) {
-                               $data = @gzdecode($contents);
-                       }
-
-                       if ($data)
-                               $doc = DOMDocument::loadXML($data);
-               }
-
-               if ($doc) {
-
-                       $xpath = new DOMXpath($doc);
-
-                       $container = $doc->firstChild;
-
-                       if ($container && $container->hasAttribute('schema-version')) {
-                               $schema_version = $container->getAttribute('schema-version');
-
-                               if ($schema_version != SCHEMA_VERSION) {
-                                       print "<p>" .__("Could not import: incorrect schema version.") . "</p>";
-                                       return;
-                               }
-
-                       } else {
-                               print "<p>" . __("Could not import: unrecognized document format.") . "</p>";
-                               return;
-                       }
-
-                       $articles = $xpath->query("//article");
-
-                       foreach ($articles as $article_node) {
-                               if ($article_node->childNodes) {
-
-                                       $ref_id = 0;
-
-                                       $article = array();
-
-                                       foreach ($article_node->childNodes as $child) {
-                                               if ($child->nodeName != 'label_cache')
-                                                       $article[$child->nodeName] = db_escape_string($child->nodeValue);
-                                               else
-                                                       $article[$child->nodeName] = $child->nodeValue;
-                                       }
-
-                                       //print_r($article);
-
-                                       if ($article['guid']) {
-
-                                               ++$num_processed;
-
-                                               //db_query($link, "BEGIN");
-
-                                               //print 'GUID:' . $article['guid'] . "\n";
-
-                                               $result = db_query($link, "SELECT id FROM ttrss_entries
-                                                       WHERE guid = '".$article['guid']."'");
-
-                                               if (db_num_rows($result) == 0) {
-
-                                                       $result = db_query($link,
-                                                               "INSERT INTO ttrss_entries
-                                                                       (title,
-                                                                       guid,
-                                                                       link,
-                                                                       updated,
-                                                                       content,
-                                                                       content_hash,
-                                                                       no_orig_date,
-                                                                       date_updated,
-                                                                       date_entered,
-                                                                       comments,
-                                                                       num_comments,
-                                                                       author)
-                                                               VALUES
-                                                                       ('".$article['title']."',
-                                                                       '".$article['guid']."',
-                                                                       '".$article['link']."',
-                                                                       '".$article['updated']."',
-                                                                       '".$article['content']."',
-                                                                       '".sha1($article['content'])."',
-                                                                       false,
-                                                                       NOW(),
-                                                                       NOW(),
-                                                                       '',
-                                                                       '0',
-                                                                       '')");
-
-                                                       $result = db_query($link, "SELECT id FROM ttrss_entries
-                                                               WHERE guid = '".$article['guid']."'");
-
-                                                       if (db_num_rows($result) != 0) {
-                                                               $ref_id = db_fetch_result($result, 0, "id");
-                                                       }
-
-                                               } else {
-                                                       $ref_id = db_fetch_result($result, 0, "id");
-                                               }
-
-                                               //print "Got ref ID: $ref_id\n";
-
-                                               if ($ref_id) {
-
-                                                       $feed_url = $article['feed_url'];
-                                                       $feed_title = $article['feed_title'];
-
-                                                       $feed = 'NULL';
-
-                                                       if ($feed_url && $feed_title) {
-                                                               $result = db_query($link, "SELECT id FROM ttrss_feeds
-                                                                       WHERE feed_url = '$feed_url' AND owner_uid = '$owner_uid'");
-
-                                                               if (db_num_rows($result) != 0) {
-                                                                       $feed = db_fetch_result($result, 0, "id");
-                                                               } else {
-                                                                       // try autocreating feed in Uncategorized...
-
-                                                                       $result = db_query($link, "INSERT INTO ttrss_feeds (owner_uid,
-                                                                               feed_url, title) VALUES ($owner_uid, '$feed_url', '$feed_title')");
-
-                                                                       $result = db_query($link, "SELECT id FROM ttrss_feeds
-                                                                               WHERE feed_url = '$feed_url' AND owner_uid = '$owner_uid'");
-
-                                                                       if (db_num_rows($result) != 0) {
-                                                                               ++$num_feeds_created;
-
-                                                                               $feed = db_fetch_result($result, 0, "id");
-                                                                       }
-                                                               }
-                                                       }
-
-                                                       if ($feed != 'NULL')
-                                                               $feed_qpart = "feed_id = $feed";
-                                                       else
-                                                               $feed_qpart = "feed_id IS NULL";
-
-                                                       //print "$ref_id / $feed / " . $article['title'] . "\n";
-
-                                                       $result = db_query($link, "SELECT int_id FROM ttrss_user_entries
-                                                               WHERE ref_id = '$ref_id' AND owner_uid = '$owner_uid' AND $feed_qpart");
-
-                                                       if (db_num_rows($result) == 0) {
-
-                                                               $marked = bool_to_sql_bool(sql_bool_to_bool($article['marked']));
-                                                               $published = bool_to_sql_bool(sql_bool_to_bool($article['published']));
-                                                               $score = (int) $article['score'];
-
-                                                               $tag_cache = $article['tag_cache'];
-                                                               $label_cache = db_escape_string($article['label_cache']);
-                                                               $note = $article['note'];
-
-                                                               //print "Importing " . $article['title'] . "<br/>";
-
-                                                               ++$num_imported;
-
-                                                               $result = db_query($link,
-                                                                       "INSERT INTO ttrss_user_entries
-                                                                       (ref_id, owner_uid, feed_id, unread, last_read, marked,
-                                                                               published, score, tag_cache, label_cache, uuid, note)
-                                                                       VALUES ($ref_id, $owner_uid, $feed, false,
-                                                                               NULL, $marked, $published, $score, '$tag_cache',
-                                                                                       '$label_cache', '', '$note')");
-
-                                                               $label_cache = json_decode($label_cache, true);
-
-                                                               if (is_array($label_cache) && $label_cache["no-labels"] != 1) {
-                                                                       foreach ($label_cache as $label) {
-
-                                                                               label_create($link, $label[1],
-                                                                                       $label[2], $label[3], $owner_uid);
-
-                                                                               label_add_article($link, $ref_id, $label[1], $owner_uid);
-
-                                                                       }
-                                                               }
-
-                                                               //db_query($link, "COMMIT");
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-
-                       print "<p>" .
-                               T_sprintf("Finished: %d articles processed, %d imported, %d feeds created.",
-                                       $num_processed, $num_imported, $num_feeds_created) .
-                                       "</p>";
-
-               } else {
-
-                       print "<p>" . __("Could not load XML document.") . "</p>";
-
-               }
-       }
-
-       function exportData() {
-
-               print "<p style='text-align : center' id='export_status_message'>You need to prepare exported data first by clicking the button below.</p>";
-
-               print "<div align='center'>";
-               print "<button dojoType=\"dijit.form.Button\"
-                       onclick=\"dijit.byId('dataExportDlg').prepare()\">".
-                       __('Prepare data')."</button>";
-
-               print "<button dojoType=\"dijit.form.Button\"
-                       onclick=\"dijit.byId('dataExportDlg').hide()\">".
-                       __('Close this window')."</button>";
-
-               print "</div>";
-
-
-       }
-
-       function dataImport() {
-               header("Content-Type: text/html"); # required for iframe
-
-               print "<div style='text-align : center'>";
-
-               if (is_file($_FILES['export_file']['tmp_name'])) {
-
-                       $this->perform_data_import($this->link, $_FILES['export_file']['tmp_name'], $_SESSION['uid']);
-
-               } else {
-                       print "<p>" . T_sprintf("Could not upload file. You might need to adjust upload_max_filesize
-                               in PHP.ini (current value = %s)", ini_get("upload_max_filesize")) . " or use CLI import tool.</p>";
-
-               }
-
-               print "<button dojoType=\"dijit.form.Button\"
-                       onclick=\"dijit.byId('dataImportDlg').hide()\">".
-                       __('Close this window')."</button>";
-
-               print "</div>";
-
-       }
-
-
-}
-?>
diff --git a/plugins/import_export/init.php b/plugins/import_export/init.php
new file mode 100644 (file)
index 0000000..de21dbf
--- /dev/null
@@ -0,0 +1,439 @@
+<?php
+class Import_Export extends Plugin implements IHandler {
+
+       private $link;
+       private $host;
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_hook($host::HOOK_PREFS_TAB, $this);
+               $host->add_command("xml-import", "USER FILE: import articles from XML", $this);
+       }
+
+       function about() {
+               return array(1.0,
+                       "Imports and exports user data using neutral XML format",
+                       "fox");
+       }
+
+       function xml_import($args) {
+               array_shift($args);
+
+               $username = $args[count($args) - 2];
+               $filename = $args[count($args) - 1];
+
+               if (!$username) {
+                       print "error: please specify username.\n";
+                       return;
+               }
+
+               if (!is_file($filename)) {
+                       print "error: input filename ($filename) doesn't exist.\n";
+                       return;
+               }
+
+               _debug("importing $filename for user $username...\n");
+
+               $result = db_query($this->link, "SELECT id FROM ttrss_users WHERE login = '$username'");
+
+               if (db_num_rows($result) == 0) {
+                       print "error: could not find user $username.\n";
+                       return;
+               }
+
+               $owner_uid = db_fetch_result($result, 0, "id");
+
+               $this->perform_data_import($this->link, $filename, $owner_uid);
+       }
+
+       function save() {
+               $example_value = db_escape_string($_POST["example_value"]);
+
+               echo "Value set to $example_value (not really)";
+       }
+
+       function get_prefs_js() {
+               return file_get_contents(dirname(__FILE__) . "/import_export.js");
+       }
+
+       function hook_prefs_tab($args) {
+               if ($args != "prefFeeds") return;
+
+               print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__('Import and export')."\">";
+
+               print "<h3>" . __("Article archive") . "</h3>";
+
+               print "<p>" . __("You can export and import your Starred and Archived articles for safekeeping or when migrating between tt-rss instances.") . "</p>";
+
+               print "<button dojoType=\"dijit.form.Button\" onclick=\"return exportData()\">".
+                       __('Export my data')."</button> ";
+
+               print "<hr>";
+
+               print "<iframe id=\"data_upload_iframe\"
+                       name=\"data_upload_iframe\" onload=\"dataImportComplete(this)\"
+                       style=\"width: 400px; height: 100px; display: none;\"></iframe>";
+
+               print "<form name=\"import_form\" style='display : block' target=\"data_upload_iframe\"
+                       enctype=\"multipart/form-data\" method=\"POST\"
+                       action=\"backend.php\">
+                       <input id=\"export_file\" name=\"export_file\" type=\"file\">&nbsp;
+                       <input type=\"hidden\" name=\"op\" value=\"pluginhandler\">
+                       <input type=\"hidden\" name=\"plugin\" value=\"import_export\">
+                       <input type=\"hidden\" name=\"method\" value=\"dataimport\">
+                       <button dojoType=\"dijit.form.Button\" onclick=\"return importData();\" type=\"submit\">" .
+                       __('Import') . "</button>";
+
+
+               print "</div>"; # pane
+       }
+
+       function csrf_ignore($method) {
+               return in_array($method, array("exportget"));
+       }
+
+       function before($method) {
+               return $_SESSION["uid"] != false;
+       }
+
+       function after() {
+               return true;
+       }
+
+       function exportget() {
+               $exportname = CACHE_DIR . "/export/" .
+                       sha1($_SESSION['uid'] . $_SESSION['login']) . ".xml";
+
+               if (file_exists($exportname)) {
+                       header("Content-type: text/xml");
+
+                       if (function_exists('gzencode')) {
+                               header("Content-Disposition: attachment; filename=TinyTinyRSS_exported.xml.gz");
+                               echo gzencode(file_get_contents($exportname));
+                       } else {
+                               header("Content-Disposition: attachment; filename=TinyTinyRSS_exported.xml");
+                               echo file_get_contents($exportname);
+                       }
+               } else {
+                       echo "File not found.";
+               }
+       }
+
+       function exportrun() {
+               $offset = (int) db_escape_string($_REQUEST['offset']);
+               $exported = 0;
+               $limit = 250;
+
+               if ($offset < 10000 && is_writable(CACHE_DIR . "/export")) {
+                       $result = db_query($this->link, "SELECT
+                                       ttrss_entries.guid,
+                                       ttrss_entries.title,
+                                       content,
+                                       marked,
+                                       published,
+                                       score,
+                                       note,
+                                       link,
+                                       tag_cache,
+                                       label_cache,
+                                       ttrss_feeds.title AS feed_title,
+                                       ttrss_feeds.feed_url AS feed_url,
+                                       ttrss_entries.updated
+                               FROM
+                                       ttrss_user_entries LEFT JOIN ttrss_feeds ON (ttrss_feeds.id = feed_id),
+                                       ttrss_entries
+                               WHERE
+                                       (marked = true OR feed_id IS NULL) AND
+                                       ref_id = ttrss_entries.id AND
+                                       ttrss_user_entries.owner_uid = " . $_SESSION['uid'] . "
+                               ORDER BY ttrss_entries.id LIMIT $limit OFFSET $offset");
+
+                       $exportname = sha1($_SESSION['uid'] . $_SESSION['login']);
+
+                       if ($offset == 0) {
+                               $fp = fopen(CACHE_DIR . "/export/$exportname.xml", "w");
+                               fputs($fp, "<articles schema-version=\"".SCHEMA_VERSION."\">");
+                       } else {
+                               $fp = fopen(CACHE_DIR . "/export/$exportname.xml", "a");
+                       }
+
+                       if ($fp) {
+
+                               while ($line = db_fetch_assoc($result)) {
+                                       fputs($fp, "<article>");
+
+                                       foreach ($line as $k => $v) {
+                                               fputs($fp, "<$k><![CDATA[$v]]></$k>");
+                                       }
+
+                                       fputs($fp, "</article>");
+                               }
+
+                               $exported = db_num_rows($result);
+
+                               if ($exported < $limit && $exported > 0) {
+                                       fputs($fp, "</articles>");
+                               }
+
+                               fclose($fp);
+                       }
+
+               }
+
+               print json_encode(array("exported" => $exported));
+       }
+
+       function perform_data_import($link, $filename, $owner_uid) {
+
+               $num_imported = 0;
+               $num_processed = 0;
+               $num_feeds_created = 0;
+
+               $doc = @DOMDocument::load($filename);
+
+               if (!$doc) {
+                       $contents = file_get_contents($filename);
+
+                       if ($contents) {
+                               $data = @gzuncompress($contents);
+                       }
+
+                       if (!$data) {
+                               $data = @gzdecode($contents);
+                       }
+
+                       if ($data)
+                               $doc = DOMDocument::loadXML($data);
+               }
+
+               if ($doc) {
+
+                       $xpath = new DOMXpath($doc);
+
+                       $container = $doc->firstChild;
+
+                       if ($container && $container->hasAttribute('schema-version')) {
+                               $schema_version = $container->getAttribute('schema-version');
+
+                               if ($schema_version != SCHEMA_VERSION) {
+                                       print "<p>" .__("Could not import: incorrect schema version.") . "</p>";
+                                       return;
+                               }
+
+                       } else {
+                               print "<p>" . __("Could not import: unrecognized document format.") . "</p>";
+                               return;
+                       }
+
+                       $articles = $xpath->query("//article");
+
+                       foreach ($articles as $article_node) {
+                               if ($article_node->childNodes) {
+
+                                       $ref_id = 0;
+
+                                       $article = array();
+
+                                       foreach ($article_node->childNodes as $child) {
+                                               if ($child->nodeName != 'label_cache')
+                                                       $article[$child->nodeName] = db_escape_string($child->nodeValue);
+                                               else
+                                                       $article[$child->nodeName] = $child->nodeValue;
+                                       }
+
+                                       //print_r($article);
+
+                                       if ($article['guid']) {
+
+                                               ++$num_processed;
+
+                                               //db_query($link, "BEGIN");
+
+                                               //print 'GUID:' . $article['guid'] . "\n";
+
+                                               $result = db_query($link, "SELECT id FROM ttrss_entries
+                                                       WHERE guid = '".$article['guid']."'");
+
+                                               if (db_num_rows($result) == 0) {
+
+                                                       $result = db_query($link,
+                                                               "INSERT INTO ttrss_entries
+                                                                       (title,
+                                                                       guid,
+                                                                       link,
+                                                                       updated,
+                                                                       content,
+                                                                       content_hash,
+                                                                       no_orig_date,
+                                                                       date_updated,
+                                                                       date_entered,
+                                                                       comments,
+                                                                       num_comments,
+                                                                       author)
+                                                               VALUES
+                                                                       ('".$article['title']."',
+                                                                       '".$article['guid']."',
+                                                                       '".$article['link']."',
+                                                                       '".$article['updated']."',
+                                                                       '".$article['content']."',
+                                                                       '".sha1($article['content'])."',
+                                                                       false,
+                                                                       NOW(),
+                                                                       NOW(),
+                                                                       '',
+                                                                       '0',
+                                                                       '')");
+
+                                                       $result = db_query($link, "SELECT id FROM ttrss_entries
+                                                               WHERE guid = '".$article['guid']."'");
+
+                                                       if (db_num_rows($result) != 0) {
+                                                               $ref_id = db_fetch_result($result, 0, "id");
+                                                       }
+
+                                               } else {
+                                                       $ref_id = db_fetch_result($result, 0, "id");
+                                               }
+
+                                               //print "Got ref ID: $ref_id\n";
+
+                                               if ($ref_id) {
+
+                                                       $feed_url = $article['feed_url'];
+                                                       $feed_title = $article['feed_title'];
+
+                                                       $feed = 'NULL';
+
+                                                       if ($feed_url && $feed_title) {
+                                                               $result = db_query($link, "SELECT id FROM ttrss_feeds
+                                                                       WHERE feed_url = '$feed_url' AND owner_uid = '$owner_uid'");
+
+                                                               if (db_num_rows($result) != 0) {
+                                                                       $feed = db_fetch_result($result, 0, "id");
+                                                               } else {
+                                                                       // try autocreating feed in Uncategorized...
+
+                                                                       $result = db_query($link, "INSERT INTO ttrss_feeds (owner_uid,
+                                                                               feed_url, title) VALUES ($owner_uid, '$feed_url', '$feed_title')");
+
+                                                                       $result = db_query($link, "SELECT id FROM ttrss_feeds
+                                                                               WHERE feed_url = '$feed_url' AND owner_uid = '$owner_uid'");
+
+                                                                       if (db_num_rows($result) != 0) {
+                                                                               ++$num_feeds_created;
+
+                                                                               $feed = db_fetch_result($result, 0, "id");
+                                                                       }
+                                                               }
+                                                       }
+
+                                                       if ($feed != 'NULL')
+                                                               $feed_qpart = "feed_id = $feed";
+                                                       else
+                                                               $feed_qpart = "feed_id IS NULL";
+
+                                                       //print "$ref_id / $feed / " . $article['title'] . "\n";
+
+                                                       $result = db_query($link, "SELECT int_id FROM ttrss_user_entries
+                                                               WHERE ref_id = '$ref_id' AND owner_uid = '$owner_uid' AND $feed_qpart");
+
+                                                       if (db_num_rows($result) == 0) {
+
+                                                               $marked = bool_to_sql_bool(sql_bool_to_bool($article['marked']));
+                                                               $published = bool_to_sql_bool(sql_bool_to_bool($article['published']));
+                                                               $score = (int) $article['score'];
+
+                                                               $tag_cache = $article['tag_cache'];
+                                                               $label_cache = db_escape_string($article['label_cache']);
+                                                               $note = $article['note'];
+
+                                                               //print "Importing " . $article['title'] . "<br/>";
+
+                                                               ++$num_imported;
+
+                                                               $result = db_query($link,
+                                                                       "INSERT INTO ttrss_user_entries
+                                                                       (ref_id, owner_uid, feed_id, unread, last_read, marked,
+                                                                               published, score, tag_cache, label_cache, uuid, note)
+                                                                       VALUES ($ref_id, $owner_uid, $feed, false,
+                                                                               NULL, $marked, $published, $score, '$tag_cache',
+                                                                                       '$label_cache', '', '$note')");
+
+                                                               $label_cache = json_decode($label_cache, true);
+
+                                                               if (is_array($label_cache) && $label_cache["no-labels"] != 1) {
+                                                                       foreach ($label_cache as $label) {
+
+                                                                               label_create($link, $label[1],
+                                                                                       $label[2], $label[3], $owner_uid);
+
+                                                                               label_add_article($link, $ref_id, $label[1], $owner_uid);
+
+                                                                       }
+                                                               }
+
+                                                               //db_query($link, "COMMIT");
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+
+                       print "<p>" .
+                               T_sprintf("Finished: %d articles processed, %d imported, %d feeds created.",
+                                       $num_processed, $num_imported, $num_feeds_created) .
+                                       "</p>";
+
+               } else {
+
+                       print "<p>" . __("Could not load XML document.") . "</p>";
+
+               }
+       }
+
+       function exportData() {
+
+               print "<p style='text-align : center' id='export_status_message'>You need to prepare exported data first by clicking the button below.</p>";
+
+               print "<div align='center'>";
+               print "<button dojoType=\"dijit.form.Button\"
+                       onclick=\"dijit.byId('dataExportDlg').prepare()\">".
+                       __('Prepare data')."</button>";
+
+               print "<button dojoType=\"dijit.form.Button\"
+                       onclick=\"dijit.byId('dataExportDlg').hide()\">".
+                       __('Close this window')."</button>";
+
+               print "</div>";
+
+
+       }
+
+       function dataImport() {
+               header("Content-Type: text/html"); # required for iframe
+
+               print "<div style='text-align : center'>";
+
+               if (is_file($_FILES['export_file']['tmp_name'])) {
+
+                       $this->perform_data_import($this->link, $_FILES['export_file']['tmp_name'], $_SESSION['uid']);
+
+               } else {
+                       print "<p>" . T_sprintf("Could not upload file. You might need to adjust upload_max_filesize
+                               in PHP.ini (current value = %s)", ini_get("upload_max_filesize")) . " or use CLI import tool.</p>";
+
+               }
+
+               print "<button dojoType=\"dijit.form.Button\"
+                       onclick=\"dijit.byId('dataImportDlg').hide()\">".
+                       __('Close this window')."</button>";
+
+               print "</div>";
+
+       }
+
+
+}
+?>
diff --git a/plugins/instances/init.php b/plugins/instances/init.php
new file mode 100644 (file)
index 0000000..3acb163
--- /dev/null
@@ -0,0 +1,398 @@
+<?php
+class Instances extends Plugin implements IHandler {
+
+       private $link;
+       private $host;
+
+       private $status_codes = array(
+               0       => "Connection failed",
+               1       => "Success",
+               2       => "Invalid object received",
+               16      => "Access denied" );
+
+       function about() {
+               return array(1.0,
+                       "Support for linking tt-rss instances together and sharing popular feeds.",
+                       "fox",
+                       true);
+       }
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_hook($host::HOOK_PREFS_TABS, $this);
+               $host->add_handler("pref-instances", "*", $this);
+               $host->add_handler("public", "fbexport", $this);
+               $host->add_command("get-feeds", "receive popular feeds from linked instances", $this);
+               $host->add_hook($host::HOOK_UPDATE_TASK, $this);
+       }
+
+       function hook_update_task($args) {
+               _debug("Get linked feeds...");
+               $this->get_linked_feeds($this->link);
+       }
+
+       // Status codes:
+       // -1  - never connected
+       // 0   - no data received
+       // 1   - data received successfully
+       // 2   - did not receive valid data
+       // >10 - server error, code + 10 (e.g. 16 means server error 6)
+
+       function get_linked_feeds($link, $instance_id = false) {
+               if ($instance_id)
+                       $instance_qpart = "id = '$instance_id' AND ";
+               else
+                       $instance_qpart = "";
+
+               if (DB_TYPE == "pgsql") {
+                       $date_qpart = "last_connected < NOW() - INTERVAL '6 hours'";
+               } else {
+                       $date_qpart = "last_connected < DATE_SUB(NOW(), INTERVAL 6 HOUR)";
+               }
+
+               $result = db_query($link, "SELECT id, access_key, access_url FROM ttrss_linked_instances
+                       WHERE $instance_qpart $date_qpart ORDER BY last_connected");
+
+               while ($line = db_fetch_assoc($result)) {
+                       $id = $line['id'];
+
+                       _debug("Updating: " . $line['access_url'] . " ($id)");
+
+                       $fetch_url = $line['access_url'] . '/public.php?op=fbexport';
+                       $post_query = 'key=' . $line['access_key'];
+
+                       $feeds = fetch_file_contents($fetch_url, false, false, false, $post_query);
+
+                       // try doing it the old way
+                       if (!$feeds) {
+                               $fetch_url = $line['access_url'] . '/backend.php?op=fbexport';
+                               $feeds = fetch_file_contents($fetch_url, false, false, false, $post_query);
+                       }
+
+                       if ($feeds) {
+                               $feeds = json_decode($feeds, true);
+
+                               if ($feeds) {
+                                       if ($feeds['error']) {
+                                               $status = $feeds['error']['code'] + 10;
+
+                                               // access denied
+                                               if ($status == 16) {
+                                                       db_query($link, "DELETE FROM ttrss_linked_feeds
+                                                               WHERE instance_id = '$id'");
+                                               }
+                                       } else {
+                                               $status = 1;
+
+                                               if (count($feeds['feeds']) > 0) {
+
+                                                       db_query($link, "DELETE FROM ttrss_linked_feeds
+                                                               WHERE instance_id = '$id'");
+
+                                                       foreach ($feeds['feeds'] as $feed) {
+                                                               $feed_url = db_escape_string($feed['feed_url']);
+                                                               $title = db_escape_string($feed['title']);
+                                                               $subscribers = db_escape_string($feed['subscribers']);
+                                                               $site_url = db_escape_string($feed['site_url']);
+
+                                                               db_query($link, "INSERT INTO ttrss_linked_feeds
+                                                                       (feed_url, site_url, title, subscribers, instance_id, created, updated)
+                                                               VALUES
+                                                                       ('$feed_url', '$site_url', '$title', '$subscribers', '$id', NOW(), NOW())");
+                                                       }
+                                               } else {
+                                                       // received 0 feeds, this might indicate that
+                                                       // the instance on the other hand is rebuilding feedbrowser cache
+                                                       // we will try again later
+
+                                                       // TODO: maybe perform expiration based on updated here?
+                                               }
+
+                                               _debug("Processed " . count($feeds['feeds']) . " feeds.");
+                                       }
+                               } else {
+                                       $status = 2;
+                               }
+
+                       } else {
+                               $status = 0;
+                       }
+
+                       _debug("Status: $status");
+
+                       db_query($link, "UPDATE ttrss_linked_instances SET
+                               last_status_out = '$status', last_connected = NOW() WHERE id = '$id'");
+
+               }
+       }
+
+
+       function get_feeds() {
+               $this->get_linked_feeds($this->link, false);
+       }
+
+       function get_prefs_js() {
+               return file_get_contents(dirname(__FILE__) . "/instances.js");
+       }
+
+       function hook_prefs_tabs($args) {
+               if ($_SESSION["access_level"] >= 10 || SINGLE_USER_MODE) {
+                       ?><div id="instanceConfigTab" dojoType="dijit.layout.ContentPane"
+                       href="backend.php?op=pref-instances"
+                       title="<?php echo __('Linked') ?>"></div><?php
+               }
+       }
+
+       function csrf_ignore($method) {
+               $csrf_ignored = array("index", "edit");
+
+               return array_search($method, $csrf_ignored) !== false;
+       }
+
+       function before($method) {
+               if ($_SESSION["uid"]) {
+                       if ($_SESSION["access_level"] < 10) {
+                               print __("Your access level is insufficient to open this tab.");
+                               return false;
+                       }
+                       return true;
+               }
+               return false;
+       }
+
+       function after() {
+               return true;
+       }
+
+       function remove() {
+               $ids = db_escape_string($_REQUEST['ids']);
+
+               db_query($this->link, "DELETE FROM ttrss_linked_instances WHERE
+                       id IN ($ids)");
+       }
+
+       function add() {
+               $id = db_escape_string($_REQUEST["id"]);
+               $access_url = db_escape_string($_REQUEST["access_url"]);
+               $access_key = db_escape_string($_REQUEST["access_key"]);
+
+               db_query($this->link, "BEGIN");
+
+               $result = db_query($this->link, "SELECT id FROM ttrss_linked_instances
+                       WHERE access_url = '$access_url'");
+
+               if (db_num_rows($result) == 0) {
+                       db_query($this->link, "INSERT INTO ttrss_linked_instances
+                               (access_url, access_key, last_connected, last_status_in, last_status_out)
+                               VALUES
+                               ('$access_url', '$access_key', '1970-01-01', -1, -1)");
+
+               }
+
+               db_query($this->link, "COMMIT");
+       }
+
+       function edit() {
+               $id = db_escape_string($_REQUEST["id"]);
+
+               $result = db_query($this->link, "SELECT * FROM ttrss_linked_instances WHERE
+                       id = '$id'");
+
+               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\"  name=\"id\" value=\"$id\">";
+               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\"  name=\"op\" value=\"pref-instances\">";
+               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\"  name=\"method\" value=\"editSave\">";
+
+               print "<div class=\"dlgSec\">".__("Instance")."</div>";
+
+               print "<div class=\"dlgSecCont\">";
+
+               /* URL */
+
+               $access_url = htmlspecialchars(db_fetch_result($result, 0, "access_url"));
+
+               print __("URL:") . " ";
+
+               print "<input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\"
+                       placeHolder=\"".__("Instance URL")."\"
+                       regExp='^(http|https)://.*'
+                       style=\"font-size : 16px; width: 20em\" name=\"access_url\"
+                       value=\"$access_url\">";
+
+               print "<hr/>";
+
+               $access_key = htmlspecialchars(db_fetch_result($result, 0, "access_key"));
+
+               /* Access key */
+
+               print __("Access key:") . " ";
+
+               print "<input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\"
+                       placeHolder=\"".__("Access key")."\" regExp='\w{40}'
+                       style=\"width: 20em\" name=\"access_key\" id=\"instance_edit_key\"
+                       value=\"$access_key\">";
+
+               print "<p class='insensitive'>" . __("Use one access key for both linked instances.");
+
+               print "</div>";
+
+               print "<div class=\"dlgButtons\">
+                       <div style='float : left'>
+                               <button dojoType=\"dijit.form.Button\"
+                                       onclick=\"return dijit.byId('instanceEditDlg').regenKey()\">".
+                                       __('Generate new key')."</button>
+                       </div>
+                       <button dojoType=\"dijit.form.Button\"
+                               onclick=\"return dijit.byId('instanceEditDlg').execute()\">".
+                               __('Save')."</button>
+                       <button dojoType=\"dijit.form.Button\"
+                               onclick=\"return dijit.byId('instanceEditDlg').hide()\"\">".
+                               __('Cancel')."</button></div>";
+
+       }
+
+       function editSave() {
+               $id = db_escape_string($_REQUEST["id"]);
+               $access_url = db_escape_string($_REQUEST["access_url"]);
+               $access_key = db_escape_string($_REQUEST["access_key"]);
+
+               db_query($this->link, "UPDATE ttrss_linked_instances SET
+                       access_key = '$access_key', access_url = '$access_url',
+                       last_connected = '1970-01-01'
+                       WHERE id = '$id'");
+
+       }
+
+       function index() {
+
+               if (!function_exists('curl_init')) {
+                       print "<div style='padding : 1em'>";
+                       print_error("This functionality requires CURL functions. Please enable CURL in your PHP configuration (you might also want to disable open_basedir in php.ini) and reload this page.");
+                       print "</div>";
+               }
+
+               print "<div id=\"pref-instance-wrap\" dojoType=\"dijit.layout.BorderContainer\" gutters=\"false\">";
+               print "<div id=\"pref-instance-header\" dojoType=\"dijit.layout.ContentPane\" region=\"top\">";
+
+               print "<div id=\"pref-instance-toolbar\" dojoType=\"dijit.Toolbar\">";
+
+               $sort = db_escape_string($_REQUEST["sort"]);
+
+               if (!$sort || $sort == "undefined") {
+                       $sort = "access_url";
+               }
+
+               print "<div dojoType=\"dijit.form.DropDownButton\">".
+                               "<span>" . __('Select')."</span>";
+               print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
+               print "<div onclick=\"selectTableRows('prefInstanceList', 'all')\"
+                       dojoType=\"dijit.MenuItem\">".__('All')."</div>";
+               print "<div onclick=\"selectTableRows('prefInstanceList', 'none')\"
+                       dojoType=\"dijit.MenuItem\">".__('None')."</div>";
+               print "</div></div>";
+
+               print "<button dojoType=\"dijit.form.Button\" onclick=\"addInstance()\">".__('Link instance')."</button>";
+               print "<button dojoType=\"dijit.form.Button\" onclick=\"editSelectedInstance()\">".__('Edit')."</button>";
+               print "<button dojoType=\"dijit.form.Button\" onclick=\"removeSelectedInstances()\">".__('Remove')."</button>";
+
+               print "</div>"; #toolbar
+
+               $result = db_query($this->link, "SELECT *,
+                       (SELECT COUNT(*) FROM ttrss_linked_feeds
+                               WHERE instance_id = ttrss_linked_instances.id) AS num_feeds
+                       FROM ttrss_linked_instances
+                       ORDER BY $sort");
+
+               print "<p class=\"insensitive\" style='margin-left : 1em;'>" . __("You can connect other instances of Tiny Tiny RSS to this one to share Popular feeds. Link to this instance of Tiny Tiny RSS by using this URL:");
+
+               print " <a href=\"#\" onclick=\"alert('".htmlspecialchars(get_self_url_prefix())."')\">(display url)</a>";
+
+               print "<p><table width='100%' id='prefInstanceList' class='prefInstanceList' cellspacing='0'>";
+
+               print "<tr class=\"title\">
+                       <td align='center' width=\"5%\">&nbsp;</td>
+                       <td width=''><a href=\"#\" onclick=\"updateInstanceList('access_url')\">".__('Instance URL')."</a></td>
+                       <td width='20%'><a href=\"#\" onclick=\"updateInstanceList('access_key')\">".__('Access key')."</a></td>
+                       <td width='10%'><a href=\"#\" onclick=\"updateUsersList('last_connected')\">".__('Last connected')."</a></td>
+                       <td width='10%'><a href=\"#\" onclick=\"updateUsersList('last_status_out')\">".__('Status')."</a></td>
+                       <td width='10%'><a href=\"#\" onclick=\"updateUsersList('num_feeds')\">".__('Stored feeds')."</a></td>
+                       </tr>";
+
+               $lnum = 0;
+
+               while ($line = db_fetch_assoc($result)) {
+                       $class = ($lnum % 2) ? "even" : "odd";
+
+                       $id = $line['id'];
+                       $this_row_id = "id=\"LIRR-$id\"";
+
+                       $line["last_connected"] = make_local_datetime($this->link, $line["last_connected"], false);
+
+                       print "<tr class=\"$class\" $this_row_id>";
+
+                       print "<td align='center'><input onclick='toggleSelectRow(this);'
+                               type=\"checkbox\" id=\"LICHK-$id\"></td>";
+
+                       $onclick = "onclick='editInstance($id, event)' title='".__('Click to edit')."'";
+
+                       $access_key = mb_substr($line['access_key'], 0, 4) . '...' .
+                               mb_substr($line['access_key'], -4);
+
+                       print "<td $onclick>" . htmlspecialchars($line['access_url']) . "</td>";
+                       print "<td $onclick>" . htmlspecialchars($access_key) . "</td>";
+                       print "<td $onclick>" . htmlspecialchars($line['last_connected']) . "</td>";
+                       print "<td $onclick>" . $this->status_codes[$line['last_status_out']] . "</td>";
+                       print "<td $onclick>" . htmlspecialchars($line['num_feeds']) . "</td>";
+
+                       print "</tr>";
+
+                       ++$lnum;
+               }
+
+               print "</table>";
+
+               print "</div>"; #pane
+
+               global $pluginhost;
+               $pluginhost->run_hooks($pluginhost::HOOK_PREFS_TAB,
+                       "hook_prefs_tab", "prefInstances");
+
+               print "</div>"; #container
+
+       }
+
+       function fbexport() {
+
+               $access_key = db_escape_string($_POST["key"]);
+
+               // TODO: rate limit checking using last_connected
+               $result = db_query($this->link, "SELECT id FROM ttrss_linked_instances
+                       WHERE access_key = '$access_key'");
+
+               if (db_num_rows($result) == 1) {
+
+                       $instance_id = db_fetch_result($result, 0, "id");
+
+                       $result = db_query($this->link, "SELECT feed_url, site_url, title, subscribers
+                               FROM ttrss_feedbrowser_cache ORDER BY subscribers DESC LIMIT 100");
+
+                       $feeds = array();
+
+                       while ($line = db_fetch_assoc($result)) {
+                               array_push($feeds, $line);
+                       }
+
+                       db_query($this->link, "UPDATE ttrss_linked_instances SET
+                               last_status_in = 1 WHERE id = '$instance_id'");
+
+                       print json_encode(array("feeds" => $feeds));
+               } else {
+                       print json_encode(array("error" => array("code" => 6)));
+               }
+       }
+
+
+}
+?>
+
diff --git a/plugins/instances/instances.php b/plugins/instances/instances.php
deleted file mode 100644 (file)
index 3acb163..0000000
+++ /dev/null
@@ -1,398 +0,0 @@
-<?php
-class Instances extends Plugin implements IHandler {
-
-       private $link;
-       private $host;
-
-       private $status_codes = array(
-               0       => "Connection failed",
-               1       => "Success",
-               2       => "Invalid object received",
-               16      => "Access denied" );
-
-       function about() {
-               return array(1.0,
-                       "Support for linking tt-rss instances together and sharing popular feeds.",
-                       "fox",
-                       true);
-       }
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-
-               $host->add_hook($host::HOOK_PREFS_TABS, $this);
-               $host->add_handler("pref-instances", "*", $this);
-               $host->add_handler("public", "fbexport", $this);
-               $host->add_command("get-feeds", "receive popular feeds from linked instances", $this);
-               $host->add_hook($host::HOOK_UPDATE_TASK, $this);
-       }
-
-       function hook_update_task($args) {
-               _debug("Get linked feeds...");
-               $this->get_linked_feeds($this->link);
-       }
-
-       // Status codes:
-       // -1  - never connected
-       // 0   - no data received
-       // 1   - data received successfully
-       // 2   - did not receive valid data
-       // >10 - server error, code + 10 (e.g. 16 means server error 6)
-
-       function get_linked_feeds($link, $instance_id = false) {
-               if ($instance_id)
-                       $instance_qpart = "id = '$instance_id' AND ";
-               else
-                       $instance_qpart = "";
-
-               if (DB_TYPE == "pgsql") {
-                       $date_qpart = "last_connected < NOW() - INTERVAL '6 hours'";
-               } else {
-                       $date_qpart = "last_connected < DATE_SUB(NOW(), INTERVAL 6 HOUR)";
-               }
-
-               $result = db_query($link, "SELECT id, access_key, access_url FROM ttrss_linked_instances
-                       WHERE $instance_qpart $date_qpart ORDER BY last_connected");
-
-               while ($line = db_fetch_assoc($result)) {
-                       $id = $line['id'];
-
-                       _debug("Updating: " . $line['access_url'] . " ($id)");
-
-                       $fetch_url = $line['access_url'] . '/public.php?op=fbexport';
-                       $post_query = 'key=' . $line['access_key'];
-
-                       $feeds = fetch_file_contents($fetch_url, false, false, false, $post_query);
-
-                       // try doing it the old way
-                       if (!$feeds) {
-                               $fetch_url = $line['access_url'] . '/backend.php?op=fbexport';
-                               $feeds = fetch_file_contents($fetch_url, false, false, false, $post_query);
-                       }
-
-                       if ($feeds) {
-                               $feeds = json_decode($feeds, true);
-
-                               if ($feeds) {
-                                       if ($feeds['error']) {
-                                               $status = $feeds['error']['code'] + 10;
-
-                                               // access denied
-                                               if ($status == 16) {
-                                                       db_query($link, "DELETE FROM ttrss_linked_feeds
-                                                               WHERE instance_id = '$id'");
-                                               }
-                                       } else {
-                                               $status = 1;
-
-                                               if (count($feeds['feeds']) > 0) {
-
-                                                       db_query($link, "DELETE FROM ttrss_linked_feeds
-                                                               WHERE instance_id = '$id'");
-
-                                                       foreach ($feeds['feeds'] as $feed) {
-                                                               $feed_url = db_escape_string($feed['feed_url']);
-                                                               $title = db_escape_string($feed['title']);
-                                                               $subscribers = db_escape_string($feed['subscribers']);
-                                                               $site_url = db_escape_string($feed['site_url']);
-
-                                                               db_query($link, "INSERT INTO ttrss_linked_feeds
-                                                                       (feed_url, site_url, title, subscribers, instance_id, created, updated)
-                                                               VALUES
-                                                                       ('$feed_url', '$site_url', '$title', '$subscribers', '$id', NOW(), NOW())");
-                                                       }
-                                               } else {
-                                                       // received 0 feeds, this might indicate that
-                                                       // the instance on the other hand is rebuilding feedbrowser cache
-                                                       // we will try again later
-
-                                                       // TODO: maybe perform expiration based on updated here?
-                                               }
-
-                                               _debug("Processed " . count($feeds['feeds']) . " feeds.");
-                                       }
-                               } else {
-                                       $status = 2;
-                               }
-
-                       } else {
-                               $status = 0;
-                       }
-
-                       _debug("Status: $status");
-
-                       db_query($link, "UPDATE ttrss_linked_instances SET
-                               last_status_out = '$status', last_connected = NOW() WHERE id = '$id'");
-
-               }
-       }
-
-
-       function get_feeds() {
-               $this->get_linked_feeds($this->link, false);
-       }
-
-       function get_prefs_js() {
-               return file_get_contents(dirname(__FILE__) . "/instances.js");
-       }
-
-       function hook_prefs_tabs($args) {
-               if ($_SESSION["access_level"] >= 10 || SINGLE_USER_MODE) {
-                       ?><div id="instanceConfigTab" dojoType="dijit.layout.ContentPane"
-                       href="backend.php?op=pref-instances"
-                       title="<?php echo __('Linked') ?>"></div><?php
-               }
-       }
-
-       function csrf_ignore($method) {
-               $csrf_ignored = array("index", "edit");
-
-               return array_search($method, $csrf_ignored) !== false;
-       }
-
-       function before($method) {
-               if ($_SESSION["uid"]) {
-                       if ($_SESSION["access_level"] < 10) {
-                               print __("Your access level is insufficient to open this tab.");
-                               return false;
-                       }
-                       return true;
-               }
-               return false;
-       }
-
-       function after() {
-               return true;
-       }
-
-       function remove() {
-               $ids = db_escape_string($_REQUEST['ids']);
-
-               db_query($this->link, "DELETE FROM ttrss_linked_instances WHERE
-                       id IN ($ids)");
-       }
-
-       function add() {
-               $id = db_escape_string($_REQUEST["id"]);
-               $access_url = db_escape_string($_REQUEST["access_url"]);
-               $access_key = db_escape_string($_REQUEST["access_key"]);
-
-               db_query($this->link, "BEGIN");
-
-               $result = db_query($this->link, "SELECT id FROM ttrss_linked_instances
-                       WHERE access_url = '$access_url'");
-
-               if (db_num_rows($result) == 0) {
-                       db_query($this->link, "INSERT INTO ttrss_linked_instances
-                               (access_url, access_key, last_connected, last_status_in, last_status_out)
-                               VALUES
-                               ('$access_url', '$access_key', '1970-01-01', -1, -1)");
-
-               }
-
-               db_query($this->link, "COMMIT");
-       }
-
-       function edit() {
-               $id = db_escape_string($_REQUEST["id"]);
-
-               $result = db_query($this->link, "SELECT * FROM ttrss_linked_instances WHERE
-                       id = '$id'");
-
-               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\"  name=\"id\" value=\"$id\">";
-               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\"  name=\"op\" value=\"pref-instances\">";
-               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\"  name=\"method\" value=\"editSave\">";
-
-               print "<div class=\"dlgSec\">".__("Instance")."</div>";
-
-               print "<div class=\"dlgSecCont\">";
-
-               /* URL */
-
-               $access_url = htmlspecialchars(db_fetch_result($result, 0, "access_url"));
-
-               print __("URL:") . " ";
-
-               print "<input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\"
-                       placeHolder=\"".__("Instance URL")."\"
-                       regExp='^(http|https)://.*'
-                       style=\"font-size : 16px; width: 20em\" name=\"access_url\"
-                       value=\"$access_url\">";
-
-               print "<hr/>";
-
-               $access_key = htmlspecialchars(db_fetch_result($result, 0, "access_key"));
-
-               /* Access key */
-
-               print __("Access key:") . " ";
-
-               print "<input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\"
-                       placeHolder=\"".__("Access key")."\" regExp='\w{40}'
-                       style=\"width: 20em\" name=\"access_key\" id=\"instance_edit_key\"
-                       value=\"$access_key\">";
-
-               print "<p class='insensitive'>" . __("Use one access key for both linked instances.");
-
-               print "</div>";
-
-               print "<div class=\"dlgButtons\">
-                       <div style='float : left'>
-                               <button dojoType=\"dijit.form.Button\"
-                                       onclick=\"return dijit.byId('instanceEditDlg').regenKey()\">".
-                                       __('Generate new key')."</button>
-                       </div>
-                       <button dojoType=\"dijit.form.Button\"
-                               onclick=\"return dijit.byId('instanceEditDlg').execute()\">".
-                               __('Save')."</button>
-                       <button dojoType=\"dijit.form.Button\"
-                               onclick=\"return dijit.byId('instanceEditDlg').hide()\"\">".
-                               __('Cancel')."</button></div>";
-
-       }
-
-       function editSave() {
-               $id = db_escape_string($_REQUEST["id"]);
-               $access_url = db_escape_string($_REQUEST["access_url"]);
-               $access_key = db_escape_string($_REQUEST["access_key"]);
-
-               db_query($this->link, "UPDATE ttrss_linked_instances SET
-                       access_key = '$access_key', access_url = '$access_url',
-                       last_connected = '1970-01-01'
-                       WHERE id = '$id'");
-
-       }
-
-       function index() {
-
-               if (!function_exists('curl_init')) {
-                       print "<div style='padding : 1em'>";
-                       print_error("This functionality requires CURL functions. Please enable CURL in your PHP configuration (you might also want to disable open_basedir in php.ini) and reload this page.");
-                       print "</div>";
-               }
-
-               print "<div id=\"pref-instance-wrap\" dojoType=\"dijit.layout.BorderContainer\" gutters=\"false\">";
-               print "<div id=\"pref-instance-header\" dojoType=\"dijit.layout.ContentPane\" region=\"top\">";
-
-               print "<div id=\"pref-instance-toolbar\" dojoType=\"dijit.Toolbar\">";
-
-               $sort = db_escape_string($_REQUEST["sort"]);
-
-               if (!$sort || $sort == "undefined") {
-                       $sort = "access_url";
-               }
-
-               print "<div dojoType=\"dijit.form.DropDownButton\">".
-                               "<span>" . __('Select')."</span>";
-               print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
-               print "<div onclick=\"selectTableRows('prefInstanceList', 'all')\"
-                       dojoType=\"dijit.MenuItem\">".__('All')."</div>";
-               print "<div onclick=\"selectTableRows('prefInstanceList', 'none')\"
-                       dojoType=\"dijit.MenuItem\">".__('None')."</div>";
-               print "</div></div>";
-
-               print "<button dojoType=\"dijit.form.Button\" onclick=\"addInstance()\">".__('Link instance')."</button>";
-               print "<button dojoType=\"dijit.form.Button\" onclick=\"editSelectedInstance()\">".__('Edit')."</button>";
-               print "<button dojoType=\"dijit.form.Button\" onclick=\"removeSelectedInstances()\">".__('Remove')."</button>";
-
-               print "</div>"; #toolbar
-
-               $result = db_query($this->link, "SELECT *,
-                       (SELECT COUNT(*) FROM ttrss_linked_feeds
-                               WHERE instance_id = ttrss_linked_instances.id) AS num_feeds
-                       FROM ttrss_linked_instances
-                       ORDER BY $sort");
-
-               print "<p class=\"insensitive\" style='margin-left : 1em;'>" . __("You can connect other instances of Tiny Tiny RSS to this one to share Popular feeds. Link to this instance of Tiny Tiny RSS by using this URL:");
-
-               print " <a href=\"#\" onclick=\"alert('".htmlspecialchars(get_self_url_prefix())."')\">(display url)</a>";
-
-               print "<p><table width='100%' id='prefInstanceList' class='prefInstanceList' cellspacing='0'>";
-
-               print "<tr class=\"title\">
-                       <td align='center' width=\"5%\">&nbsp;</td>
-                       <td width=''><a href=\"#\" onclick=\"updateInstanceList('access_url')\">".__('Instance URL')."</a></td>
-                       <td width='20%'><a href=\"#\" onclick=\"updateInstanceList('access_key')\">".__('Access key')."</a></td>
-                       <td width='10%'><a href=\"#\" onclick=\"updateUsersList('last_connected')\">".__('Last connected')."</a></td>
-                       <td width='10%'><a href=\"#\" onclick=\"updateUsersList('last_status_out')\">".__('Status')."</a></td>
-                       <td width='10%'><a href=\"#\" onclick=\"updateUsersList('num_feeds')\">".__('Stored feeds')."</a></td>
-                       </tr>";
-
-               $lnum = 0;
-
-               while ($line = db_fetch_assoc($result)) {
-                       $class = ($lnum % 2) ? "even" : "odd";
-
-                       $id = $line['id'];
-                       $this_row_id = "id=\"LIRR-$id\"";
-
-                       $line["last_connected"] = make_local_datetime($this->link, $line["last_connected"], false);
-
-                       print "<tr class=\"$class\" $this_row_id>";
-
-                       print "<td align='center'><input onclick='toggleSelectRow(this);'
-                               type=\"checkbox\" id=\"LICHK-$id\"></td>";
-
-                       $onclick = "onclick='editInstance($id, event)' title='".__('Click to edit')."'";
-
-                       $access_key = mb_substr($line['access_key'], 0, 4) . '...' .
-                               mb_substr($line['access_key'], -4);
-
-                       print "<td $onclick>" . htmlspecialchars($line['access_url']) . "</td>";
-                       print "<td $onclick>" . htmlspecialchars($access_key) . "</td>";
-                       print "<td $onclick>" . htmlspecialchars($line['last_connected']) . "</td>";
-                       print "<td $onclick>" . $this->status_codes[$line['last_status_out']] . "</td>";
-                       print "<td $onclick>" . htmlspecialchars($line['num_feeds']) . "</td>";
-
-                       print "</tr>";
-
-                       ++$lnum;
-               }
-
-               print "</table>";
-
-               print "</div>"; #pane
-
-               global $pluginhost;
-               $pluginhost->run_hooks($pluginhost::HOOK_PREFS_TAB,
-                       "hook_prefs_tab", "prefInstances");
-
-               print "</div>"; #container
-
-       }
-
-       function fbexport() {
-
-               $access_key = db_escape_string($_POST["key"]);
-
-               // TODO: rate limit checking using last_connected
-               $result = db_query($this->link, "SELECT id FROM ttrss_linked_instances
-                       WHERE access_key = '$access_key'");
-
-               if (db_num_rows($result) == 1) {
-
-                       $instance_id = db_fetch_result($result, 0, "id");
-
-                       $result = db_query($this->link, "SELECT feed_url, site_url, title, subscribers
-                               FROM ttrss_feedbrowser_cache ORDER BY subscribers DESC LIMIT 100");
-
-                       $feeds = array();
-
-                       while ($line = db_fetch_assoc($result)) {
-                               array_push($feeds, $line);
-                       }
-
-                       db_query($this->link, "UPDATE ttrss_linked_instances SET
-                               last_status_in = 1 WHERE id = '$instance_id'");
-
-                       print json_encode(array("feeds" => $feeds));
-               } else {
-                       print json_encode(array("error" => array("code" => 6)));
-               }
-       }
-
-
-}
-?>
-
diff --git a/plugins/mail/init.php b/plugins/mail/init.php
new file mode 100644 (file)
index 0000000..2e972cf
--- /dev/null
@@ -0,0 +1,212 @@
+<?php
+class Mail extends Plugin {
+
+       private $link;
+       private $host;
+
+       function about() {
+               return array(1.0,
+                       "Share article via email",
+                       "fox");
+       }
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
+       }
+
+       function get_js() {
+               return file_get_contents(dirname(__FILE__) . "/mail.js");
+       }
+
+       function hook_article_button($line) {
+               return "<img src=\"".theme_image($link, 'plugins/mail/mail.png')."\"
+                                       class='tagsPic' style=\"cursor : pointer\"
+                                       onclick=\"emailArticle(".$line["id"].")\"
+                                       alt='Zoom' title='".__('Forward by email')."'>";
+       }
+
+       function emailArticle() {
+
+               $param = db_escape_string($_REQUEST['param']);
+
+               $secretkey = sha1(uniqid(rand(), true));
+
+               $_SESSION['email_secretkey'] = $secretkey;
+
+               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"secretkey\" value=\"$secretkey\">";
+               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pluginhandler\">";
+               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"plugin\" value=\"mail\">";
+               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"sendEmail\">";
+
+               $result = db_query($this->link, "SELECT email, full_name FROM ttrss_users WHERE
+                       id = " . $_SESSION["uid"]);
+
+               $user_email = htmlspecialchars(db_fetch_result($result, 0, "email"));
+               $user_name = htmlspecialchars(db_fetch_result($result, 0, "full_name"));
+
+               if (!$user_name) $user_name = $_SESSION['name'];
+
+               $_SESSION['email_replyto'] = $user_email;
+               $_SESSION['email_fromname'] = $user_name;
+
+               require_once "lib/MiniTemplator.class.php";
+
+               $tpl = new MiniTemplator;
+               $tpl_t = new MiniTemplator;
+
+               $tpl->readTemplateFromFile("templates/email_article_template.txt");
+
+               $tpl->setVariable('USER_NAME', $_SESSION["name"]);
+               $tpl->setVariable('USER_EMAIL', $user_email);
+               $tpl->setVariable('TTRSS_HOST', $_SERVER["HTTP_HOST"]);
+
+
+               $result = db_query($this->link, "SELECT link, content, title
+                       FROM ttrss_user_entries, ttrss_entries WHERE id = ref_id AND
+                       id IN ($param) AND owner_uid = " . $_SESSION["uid"]);
+
+               if (db_num_rows($result) > 1) {
+                       $subject = __("[Forwarded]") . " " . __("Multiple articles");
+               }
+
+               while ($line = db_fetch_assoc($result)) {
+
+                       if (!$subject)
+                               $subject = __("[Forwarded]") . " " . htmlspecialchars($line["title"]);
+
+                       $tpl->setVariable('ARTICLE_TITLE', strip_tags($line["title"]));
+                       $tpl->setVariable('ARTICLE_URL', strip_tags($line["link"]));
+
+                       $tpl->addBlock('article');
+               }
+
+               $tpl->addBlock('email');
+
+               $content = "";
+               $tpl->generateOutputToString($content);
+
+               print "<table width='100%'><tr><td>";
+
+               print __('From:');
+
+               print "</td><td>";
+
+               print "<input dojoType=\"dijit.form.TextBox\" disabled=\"1\" style=\"width : 30em;\"
+                               value=\"$user_name <$user_email>\">";
+
+               print "</td></tr><tr><td>";
+
+               print __('To:');
+
+               print "</td><td>";
+
+               print "<input dojoType=\"dijit.form.ValidationTextBox\" required=\"true\"
+                               style=\"width : 30em;\"
+                               name=\"destination\" id=\"emailArticleDlg_destination\">";
+
+               print "<div class=\"autocomplete\" id=\"emailArticleDlg_dst_choices\"
+                               style=\"z-index: 30; display : none\"></div>";
+
+               print "</td></tr><tr><td>";
+
+               print __('Subject:');
+
+               print "</td><td>";
+
+               print "<input dojoType=\"dijit.form.ValidationTextBox\" required=\"true\"
+                               style=\"width : 30em;\"
+                               name=\"subject\" value=\"$subject\" id=\"subject\">";
+
+               print "</td></tr>";
+
+               print "<tr><td colspan='2'><textarea dojoType=\"dijit.form.SimpleTextarea\" style='font-size : 12px; width : 100%' rows=\"20\"
+                       name='content'>$content</textarea>";
+
+               print "</td></tr></table>";
+
+               print "<div class='dlgButtons'>";
+               print "<button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('emailArticleDlg').execute()\">".__('Send e-mail')."</button> ";
+               print "<button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('emailArticleDlg').hide()\">".__('Cancel')."</button>";
+               print "</div>";
+
+               //return;
+       }
+
+       function sendEmail() {
+               $secretkey = $_REQUEST['secretkey'];
+
+               require_once 'lib/phpmailer/class.phpmailer.php';
+
+               $reply = array();
+
+               if ($_SESSION['email_secretkey'] &&
+               $secretkey == $_SESSION['email_secretkey']) {
+
+                       $_SESSION['email_secretkey'] = '';
+
+                       $destination = $_REQUEST['destination'];
+                       $subject = $_REQUEST['subject'];
+                       $content = $_REQUEST['content'];
+
+                       $replyto = strip_tags($_SESSION['email_replyto']);
+                       $fromname = strip_tags($_SESSION['email_fromname']);
+
+                       $mail = new PHPMailer();
+
+                       $mail->PluginDir = "lib/phpmailer/";
+                       $mail->SetLanguage("en", "lib/phpmailer/language/");
+
+                       $mail->CharSet = "UTF-8";
+
+                       $mail->From = $replyto;
+                       $mail->FromName = $fromname;
+                       $mail->AddAddress($destination);
+
+                       if (SMTP_HOST) {
+                               $mail->Host = SMTP_HOST;
+                               $mail->Mailer = "smtp";
+                               $mail->SMTPAuth = SMTP_LOGIN != '';
+                               $mail->Username = SMTP_LOGIN;
+                               $mail->Password = SMTP_PASSWORD;
+                       }
+
+                       $mail->IsHTML(false);
+                       $mail->Subject = $subject;
+                       $mail->Body = $content;
+
+                       $rc = $mail->Send();
+
+                       if (!$rc) {
+                               $reply['error'] =  $mail->ErrorInfo;
+                       } else {
+                               save_email_address($this->link, db_escape_string($destination));
+                               $reply['message'] = "UPDATE_COUNTERS";
+                       }
+
+               } else {
+                       $reply['error'] = "Not authorized.";
+               }
+
+               print json_encode($reply);
+       }
+
+       function completeEmails() {
+               $search = db_escape_string($_REQUEST["search"]);
+
+               print "<ul>";
+
+               foreach ($_SESSION['stored_emails'] as $email) {
+                       if (strpos($email, $search) !== false) {
+                               print "<li>$email</li>";
+                       }
+               }
+
+               print "</ul>";
+       }
+
+
+}
+?>
diff --git a/plugins/mail/mail.php b/plugins/mail/mail.php
deleted file mode 100644 (file)
index 2e972cf..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-<?php
-class Mail extends Plugin {
-
-       private $link;
-       private $host;
-
-       function about() {
-               return array(1.0,
-                       "Share article via email",
-                       "fox");
-       }
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-
-               $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
-       }
-
-       function get_js() {
-               return file_get_contents(dirname(__FILE__) . "/mail.js");
-       }
-
-       function hook_article_button($line) {
-               return "<img src=\"".theme_image($link, 'plugins/mail/mail.png')."\"
-                                       class='tagsPic' style=\"cursor : pointer\"
-                                       onclick=\"emailArticle(".$line["id"].")\"
-                                       alt='Zoom' title='".__('Forward by email')."'>";
-       }
-
-       function emailArticle() {
-
-               $param = db_escape_string($_REQUEST['param']);
-
-               $secretkey = sha1(uniqid(rand(), true));
-
-               $_SESSION['email_secretkey'] = $secretkey;
-
-               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"secretkey\" value=\"$secretkey\">";
-               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pluginhandler\">";
-               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"plugin\" value=\"mail\">";
-               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"sendEmail\">";
-
-               $result = db_query($this->link, "SELECT email, full_name FROM ttrss_users WHERE
-                       id = " . $_SESSION["uid"]);
-
-               $user_email = htmlspecialchars(db_fetch_result($result, 0, "email"));
-               $user_name = htmlspecialchars(db_fetch_result($result, 0, "full_name"));
-
-               if (!$user_name) $user_name = $_SESSION['name'];
-
-               $_SESSION['email_replyto'] = $user_email;
-               $_SESSION['email_fromname'] = $user_name;
-
-               require_once "lib/MiniTemplator.class.php";
-
-               $tpl = new MiniTemplator;
-               $tpl_t = new MiniTemplator;
-
-               $tpl->readTemplateFromFile("templates/email_article_template.txt");
-
-               $tpl->setVariable('USER_NAME', $_SESSION["name"]);
-               $tpl->setVariable('USER_EMAIL', $user_email);
-               $tpl->setVariable('TTRSS_HOST', $_SERVER["HTTP_HOST"]);
-
-
-               $result = db_query($this->link, "SELECT link, content, title
-                       FROM ttrss_user_entries, ttrss_entries WHERE id = ref_id AND
-                       id IN ($param) AND owner_uid = " . $_SESSION["uid"]);
-
-               if (db_num_rows($result) > 1) {
-                       $subject = __("[Forwarded]") . " " . __("Multiple articles");
-               }
-
-               while ($line = db_fetch_assoc($result)) {
-
-                       if (!$subject)
-                               $subject = __("[Forwarded]") . " " . htmlspecialchars($line["title"]);
-
-                       $tpl->setVariable('ARTICLE_TITLE', strip_tags($line["title"]));
-                       $tpl->setVariable('ARTICLE_URL', strip_tags($line["link"]));
-
-                       $tpl->addBlock('article');
-               }
-
-               $tpl->addBlock('email');
-
-               $content = "";
-               $tpl->generateOutputToString($content);
-
-               print "<table width='100%'><tr><td>";
-
-               print __('From:');
-
-               print "</td><td>";
-
-               print "<input dojoType=\"dijit.form.TextBox\" disabled=\"1\" style=\"width : 30em;\"
-                               value=\"$user_name <$user_email>\">";
-
-               print "</td></tr><tr><td>";
-
-               print __('To:');
-
-               print "</td><td>";
-
-               print "<input dojoType=\"dijit.form.ValidationTextBox\" required=\"true\"
-                               style=\"width : 30em;\"
-                               name=\"destination\" id=\"emailArticleDlg_destination\">";
-
-               print "<div class=\"autocomplete\" id=\"emailArticleDlg_dst_choices\"
-                               style=\"z-index: 30; display : none\"></div>";
-
-               print "</td></tr><tr><td>";
-
-               print __('Subject:');
-
-               print "</td><td>";
-
-               print "<input dojoType=\"dijit.form.ValidationTextBox\" required=\"true\"
-                               style=\"width : 30em;\"
-                               name=\"subject\" value=\"$subject\" id=\"subject\">";
-
-               print "</td></tr>";
-
-               print "<tr><td colspan='2'><textarea dojoType=\"dijit.form.SimpleTextarea\" style='font-size : 12px; width : 100%' rows=\"20\"
-                       name='content'>$content</textarea>";
-
-               print "</td></tr></table>";
-
-               print "<div class='dlgButtons'>";
-               print "<button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('emailArticleDlg').execute()\">".__('Send e-mail')."</button> ";
-               print "<button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('emailArticleDlg').hide()\">".__('Cancel')."</button>";
-               print "</div>";
-
-               //return;
-       }
-
-       function sendEmail() {
-               $secretkey = $_REQUEST['secretkey'];
-
-               require_once 'lib/phpmailer/class.phpmailer.php';
-
-               $reply = array();
-
-               if ($_SESSION['email_secretkey'] &&
-               $secretkey == $_SESSION['email_secretkey']) {
-
-                       $_SESSION['email_secretkey'] = '';
-
-                       $destination = $_REQUEST['destination'];
-                       $subject = $_REQUEST['subject'];
-                       $content = $_REQUEST['content'];
-
-                       $replyto = strip_tags($_SESSION['email_replyto']);
-                       $fromname = strip_tags($_SESSION['email_fromname']);
-
-                       $mail = new PHPMailer();
-
-                       $mail->PluginDir = "lib/phpmailer/";
-                       $mail->SetLanguage("en", "lib/phpmailer/language/");
-
-                       $mail->CharSet = "UTF-8";
-
-                       $mail->From = $replyto;
-                       $mail->FromName = $fromname;
-                       $mail->AddAddress($destination);
-
-                       if (SMTP_HOST) {
-                               $mail->Host = SMTP_HOST;
-                               $mail->Mailer = "smtp";
-                               $mail->SMTPAuth = SMTP_LOGIN != '';
-                               $mail->Username = SMTP_LOGIN;
-                               $mail->Password = SMTP_PASSWORD;
-                       }
-
-                       $mail->IsHTML(false);
-                       $mail->Subject = $subject;
-                       $mail->Body = $content;
-
-                       $rc = $mail->Send();
-
-                       if (!$rc) {
-                               $reply['error'] =  $mail->ErrorInfo;
-                       } else {
-                               save_email_address($this->link, db_escape_string($destination));
-                               $reply['message'] = "UPDATE_COUNTERS";
-                       }
-
-               } else {
-                       $reply['error'] = "Not authorized.";
-               }
-
-               print json_encode($reply);
-       }
-
-       function completeEmails() {
-               $search = db_escape_string($_REQUEST["search"]);
-
-               print "<ul>";
-
-               foreach ($_SESSION['stored_emails'] as $email) {
-                       if (strpos($email, $search) !== false) {
-                               print "<li>$email</li>";
-                       }
-               }
-
-               print "</ul>";
-       }
-
-
-}
-?>
diff --git a/plugins/note/init.php b/plugins/note/init.php
new file mode 100644 (file)
index 0000000..560796a
--- /dev/null
@@ -0,0 +1,74 @@
+<?php
+class Note extends Plugin {
+       private $link;
+       private $host;
+
+       function about() {
+               return array(1.0,
+                       "Adds support for setting article notes",
+                       "fox");
+       }
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
+       }
+
+       function get_js() {
+               return file_get_contents(dirname(__FILE__) . "/note.js");
+       }
+
+
+       function hook_article_button($line) {
+               return "<img src=\"".theme_image($this->link, "plugins/note/note.png")."\"
+                       style=\"cursor : pointer\" style=\"cursor : pointer\"
+                       onclick=\"editArticleNote(".$line["id"].")\"
+                       class='tagsPic' title='".__('Edit article note')."'>";
+       }
+
+       function edit() {
+               $param = db_escape_string($_REQUEST['param']);
+
+               $result = db_query($this->link, "SELECT note FROM ttrss_user_entries WHERE
+                       ref_id = '$param' AND owner_uid = " . $_SESSION['uid']);
+
+               $note = db_fetch_result($result, 0, "note");
+
+               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"id\" value=\"$param\">";
+               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pluginhandler\">";
+               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"setNote\">";
+               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"plugin\" value=\"note\">";
+
+               print "<table width='100%'><tr><td>";
+               print "<textarea dojoType=\"dijit.form.SimpleTextarea\"
+                       style='font-size : 12px; width : 100%; height: 100px;'
+                       placeHolder='body#ttrssMain { font-size : 14px; };'
+                       name='note'>$note</textarea>";
+               print "</td></tr></table>";
+
+               print "<div class='dlgButtons'>";
+               print "<button dojoType=\"dijit.form.Button\"
+                       onclick=\"dijit.byId('editNoteDlg').execute()\">".__('Save')."</button> ";
+               print "<button dojoType=\"dijit.form.Button\"
+                       onclick=\"dijit.byId('editNoteDlg').hide()\">".__('Cancel')."</button>";
+               print "</div>";
+
+       }
+
+       function setNote() {
+               $id = db_escape_string($_REQUEST["id"]);
+               $note = trim(strip_tags(db_escape_string($_REQUEST["note"])));
+
+               db_query($this->link, "UPDATE ttrss_user_entries SET note = '$note'
+                       WHERE ref_id = '$id' AND owner_uid = " . $_SESSION["uid"]);
+
+               $formatted_note = format_article_note($id, $note);
+
+               print json_encode(array("note" => $formatted_note,
+                               "raw_length" => mb_strlen($note)));
+       }
+
+}
+?>
diff --git a/plugins/note/note.php b/plugins/note/note.php
deleted file mode 100644 (file)
index 560796a..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-class Note extends Plugin {
-       private $link;
-       private $host;
-
-       function about() {
-               return array(1.0,
-                       "Adds support for setting article notes",
-                       "fox");
-       }
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-
-               $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
-       }
-
-       function get_js() {
-               return file_get_contents(dirname(__FILE__) . "/note.js");
-       }
-
-
-       function hook_article_button($line) {
-               return "<img src=\"".theme_image($this->link, "plugins/note/note.png")."\"
-                       style=\"cursor : pointer\" style=\"cursor : pointer\"
-                       onclick=\"editArticleNote(".$line["id"].")\"
-                       class='tagsPic' title='".__('Edit article note')."'>";
-       }
-
-       function edit() {
-               $param = db_escape_string($_REQUEST['param']);
-
-               $result = db_query($this->link, "SELECT note FROM ttrss_user_entries WHERE
-                       ref_id = '$param' AND owner_uid = " . $_SESSION['uid']);
-
-               $note = db_fetch_result($result, 0, "note");
-
-               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"id\" value=\"$param\">";
-               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pluginhandler\">";
-               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"setNote\">";
-               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"plugin\" value=\"note\">";
-
-               print "<table width='100%'><tr><td>";
-               print "<textarea dojoType=\"dijit.form.SimpleTextarea\"
-                       style='font-size : 12px; width : 100%; height: 100px;'
-                       placeHolder='body#ttrssMain { font-size : 14px; };'
-                       name='note'>$note</textarea>";
-               print "</td></tr></table>";
-
-               print "<div class='dlgButtons'>";
-               print "<button dojoType=\"dijit.form.Button\"
-                       onclick=\"dijit.byId('editNoteDlg').execute()\">".__('Save')."</button> ";
-               print "<button dojoType=\"dijit.form.Button\"
-                       onclick=\"dijit.byId('editNoteDlg').hide()\">".__('Cancel')."</button>";
-               print "</div>";
-
-       }
-
-       function setNote() {
-               $id = db_escape_string($_REQUEST["id"]);
-               $note = trim(strip_tags(db_escape_string($_REQUEST["note"])));
-
-               db_query($this->link, "UPDATE ttrss_user_entries SET note = '$note'
-                       WHERE ref_id = '$id' AND owner_uid = " . $_SESSION["uid"]);
-
-               $formatted_note = format_article_note($id, $note);
-
-               print json_encode(array("note" => $formatted_note,
-                               "raw_length" => mb_strlen($note)));
-       }
-
-}
-?>
diff --git a/plugins/owncloud/init.php b/plugins/owncloud/init.php
new file mode 100644 (file)
index 0000000..b846241
--- /dev/null
@@ -0,0 +1,96 @@
+<?php
+require_once "config.php";
+
+class OwnCloud extends Plugin {
+  private $link;
+  private $host;
+
+  function about() {
+    return array(1.0,
+                "Adds support for OwnCloud ReadLater",
+                "cy8aer");
+  }
+
+  function init($host) {
+    $this->link = $host->get_link();
+    $this->host = $host;
+
+    $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
+    $host->add_hook($host::HOOK_PREFS_TAB, $this);
+  }
+
+  function save() {
+    $owncloud_url = db_escape_string($_POST["owncloud_url"]);
+    $this->host->set($this, "owncloud", $owncloud_url);
+    echo "Value set to $owncloud_url";
+  }
+
+  function get_js() {
+    return file_get_contents(dirname(__FILE__) . "/owncloud.js");
+  }
+
+  function hook_prefs_tab($args) {
+    if ($args != "prefPrefs") return;
+
+    print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__("Owncloud")."\">";
+
+    print "<br/>";
+
+    $value = $this->host->get($this, "owncloud");
+    print "<form dojoType=\"dijit.form.Form\">";
+
+    print "<script type=\"dojo/method\" event=\"onSubmit\" args=\"evt\">
+           evt.preventDefault();
+           if (this.validate()) {
+               console.log(dojo.objectToQuery(this.getValues()));
+               new Ajax.Request('backend.php', {
+                                    parameters: dojo.objectToQuery(this.getValues()),
+                                    onComplete: function(transport) {
+                                         notify_info(transport.responseText);
+                                    }
+                                });
+           }
+           </script>";
+
+    print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pluginhandler\">";
+    print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"save\">";
+    print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"plugin\" value=\"owncloud\">";
+    print "<table width=\"100%\" class=\"prefPrefsList\">";
+        print "<tr><td width=\"40%\">".__("Owncloud url")."</td>";
+       print "<td class=\"prefValue\"><input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\" name=\"owncloud_url\" regExp='^(http|https)://.*' value=\"$value\"></td></tr>";
+    print "</table>";
+    print "<p><button dojoType=\"dijit.form.Button\" type=\"submit\">".__("Save")."</button>";
+
+    print "</form>";
+
+    print "</div>"; #pane
+
+  }
+
+  function hook_article_button($line) {
+    return "<img src=\"".theme_image($this->link, "plugins/owncloud/owncloud.png")."\"
+             style=\"cursor : pointer\" style=\"cursor : pointer\"
+             onclick=\"ownArticle(".$line["id"].")\"
+             class='tagsPic' title='".__('Bookmark on OwnCloud ')."'>";
+  }
+
+  function getOwnCloud() {
+    $id = db_escape_string($_REQUEST['id']);
+
+    $result = db_query($this->link, "SELECT title, link
+                     FROM ttrss_entries, ttrss_user_entries
+                     WHERE id = '$id' AND ref_id = id AND owner_uid = " .$_SESSION['uid']);
+
+    if (db_num_rows($result) != 0) {
+      $title = truncate_string(strip_tags(db_fetch_result($result, 0, 'title')),
+                              100, '...');
+      $article_link = db_fetch_result($result, 0, 'link');
+    }
+
+    $own_url = $this->host->get($this, "owncloud");
+
+    print json_encode(array("title" => $title, "link" => $article_link,
+                           "id" => $id, "ownurl" => $own_url));
+  }
+}
+?>
diff --git a/plugins/owncloud/owncloud.php b/plugins/owncloud/owncloud.php
deleted file mode 100644 (file)
index b846241..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-<?php
-require_once "config.php";
-
-class OwnCloud extends Plugin {
-  private $link;
-  private $host;
-
-  function about() {
-    return array(1.0,
-                "Adds support for OwnCloud ReadLater",
-                "cy8aer");
-  }
-
-  function init($host) {
-    $this->link = $host->get_link();
-    $this->host = $host;
-
-    $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
-    $host->add_hook($host::HOOK_PREFS_TAB, $this);
-  }
-
-  function save() {
-    $owncloud_url = db_escape_string($_POST["owncloud_url"]);
-    $this->host->set($this, "owncloud", $owncloud_url);
-    echo "Value set to $owncloud_url";
-  }
-
-  function get_js() {
-    return file_get_contents(dirname(__FILE__) . "/owncloud.js");
-  }
-
-  function hook_prefs_tab($args) {
-    if ($args != "prefPrefs") return;
-
-    print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__("Owncloud")."\">";
-
-    print "<br/>";
-
-    $value = $this->host->get($this, "owncloud");
-    print "<form dojoType=\"dijit.form.Form\">";
-
-    print "<script type=\"dojo/method\" event=\"onSubmit\" args=\"evt\">
-           evt.preventDefault();
-           if (this.validate()) {
-               console.log(dojo.objectToQuery(this.getValues()));
-               new Ajax.Request('backend.php', {
-                                    parameters: dojo.objectToQuery(this.getValues()),
-                                    onComplete: function(transport) {
-                                         notify_info(transport.responseText);
-                                    }
-                                });
-           }
-           </script>";
-
-    print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pluginhandler\">";
-    print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"save\">";
-    print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"plugin\" value=\"owncloud\">";
-    print "<table width=\"100%\" class=\"prefPrefsList\">";
-        print "<tr><td width=\"40%\">".__("Owncloud url")."</td>";
-       print "<td class=\"prefValue\"><input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\" name=\"owncloud_url\" regExp='^(http|https)://.*' value=\"$value\"></td></tr>";
-    print "</table>";
-    print "<p><button dojoType=\"dijit.form.Button\" type=\"submit\">".__("Save")."</button>";
-
-    print "</form>";
-
-    print "</div>"; #pane
-
-  }
-
-  function hook_article_button($line) {
-    return "<img src=\"".theme_image($this->link, "plugins/owncloud/owncloud.png")."\"
-             style=\"cursor : pointer\" style=\"cursor : pointer\"
-             onclick=\"ownArticle(".$line["id"].")\"
-             class='tagsPic' title='".__('Bookmark on OwnCloud ')."'>";
-  }
-
-  function getOwnCloud() {
-    $id = db_escape_string($_REQUEST['id']);
-
-    $result = db_query($this->link, "SELECT title, link
-                     FROM ttrss_entries, ttrss_user_entries
-                     WHERE id = '$id' AND ref_id = id AND owner_uid = " .$_SESSION['uid']);
-
-    if (db_num_rows($result) != 0) {
-      $title = truncate_string(strip_tags(db_fetch_result($result, 0, 'title')),
-                              100, '...');
-      $article_link = db_fetch_result($result, 0, 'link');
-    }
-
-    $own_url = $this->host->get($this, "owncloud");
-
-    print json_encode(array("title" => $title, "link" => $article_link,
-                           "id" => $id, "ownurl" => $own_url));
-  }
-}
-?>
diff --git a/plugins/pinterest/init.php b/plugins/pinterest/init.php
new file mode 100644 (file)
index 0000000..aef9d85
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+class Pinterest extends Plugin {
+       private $link;
+       private $host;
+
+       function about() {
+               return array(1.0,
+                       "Share article on Pinterest",
+                       "?");
+       }
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
+       }
+
+       function get_js() {
+               return file_get_contents(dirname(__FILE__) . "/pinterest.js");
+       }
+
+       function hook_article_button($line) {
+               $article_id = $line["id"];
+
+               $rv = "<img src=\"".theme_image($this->link, 'plugins/pinterest/pinterest.png')."\"
+                       class='tagsPic' style=\"cursor : pointer\"
+                       onclick=\"pinterest($article_id)\"
+                       title='".__('Pinterest')."'>";
+
+               return $rv;
+       }
+
+       function getInfo() {
+               $id = db_escape_string($_REQUEST['id']);
+
+               $result = db_query($this->link, "SELECT title, link
+                               FROM ttrss_entries, ttrss_user_entries
+                               WHERE id = '$id' AND ref_id = id AND owner_uid = " .$_SESSION['uid']);
+
+               if (db_num_rows($result) != 0) {
+                       $title = truncate_string(strip_tags(db_fetch_result($result, 0, 'title')),
+                               100, '...');
+                       $article_link = db_fetch_result($result, 0, 'link');
+               }
+
+               print json_encode(array("title" => $title, "link" => $article_link,
+                               "id" => $id));
+       }
+
+
+}
+?>
diff --git a/plugins/pinterest/pinterest.php b/plugins/pinterest/pinterest.php
deleted file mode 100644 (file)
index aef9d85..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-class Pinterest extends Plugin {
-       private $link;
-       private $host;
-
-       function about() {
-               return array(1.0,
-                       "Share article on Pinterest",
-                       "?");
-       }
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-
-               $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
-       }
-
-       function get_js() {
-               return file_get_contents(dirname(__FILE__) . "/pinterest.js");
-       }
-
-       function hook_article_button($line) {
-               $article_id = $line["id"];
-
-               $rv = "<img src=\"".theme_image($this->link, 'plugins/pinterest/pinterest.png')."\"
-                       class='tagsPic' style=\"cursor : pointer\"
-                       onclick=\"pinterest($article_id)\"
-                       title='".__('Pinterest')."'>";
-
-               return $rv;
-       }
-
-       function getInfo() {
-               $id = db_escape_string($_REQUEST['id']);
-
-               $result = db_query($this->link, "SELECT title, link
-                               FROM ttrss_entries, ttrss_user_entries
-                               WHERE id = '$id' AND ref_id = id AND owner_uid = " .$_SESSION['uid']);
-
-               if (db_num_rows($result) != 0) {
-                       $title = truncate_string(strip_tags(db_fetch_result($result, 0, 'title')),
-                               100, '...');
-                       $article_link = db_fetch_result($result, 0, 'link');
-               }
-
-               print json_encode(array("title" => $title, "link" => $article_link,
-                               "id" => $id));
-       }
-
-
-}
-?>
diff --git a/plugins/pocket/init.php b/plugins/pocket/init.php
new file mode 100644 (file)
index 0000000..3fc51dd
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+class Pocket extends Plugin {
+
+       private $link;
+       private $host;
+
+       function about() {
+               return array(1.0,
+                       "Share article on Pocket (formerly Read It Later)",
+                       "?");
+       }
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
+       }
+
+       function get_js() {
+               return file_get_contents(dirname(__FILE__) . "/pocket.js");
+       }
+
+       function hook_article_button($line) {
+               $article_id = $line["id"];
+
+               $rv = "<img src=\"".theme_image($this->link, 'plugins/pocket/pocket.png')."\"
+                       class='tagsPic' style=\"cursor : pointer\"
+                       onclick=\"shareArticleToPocket($article_id)\"
+                       title='".__('Pocket')."'>";
+
+               return $rv;
+       }
+
+       function getInfo() {
+               $id = db_escape_string($_REQUEST['id']);
+
+               $result = db_query($this->link, "SELECT title, link
+                               FROM ttrss_entries, ttrss_user_entries
+                               WHERE id = '$id' AND ref_id = id AND owner_uid = " .$_SESSION['uid']);
+
+               if (db_num_rows($result) != 0) {
+                       $title = truncate_string(strip_tags(db_fetch_result($result, 0, 'title')),
+                               100, '...');
+                       $article_link = db_fetch_result($result, 0, 'link');
+               }
+
+               print json_encode(array("title" => $title, "link" => $article_link,
+                               "id" => $id));
+       }
+
+
+}
+?>
diff --git a/plugins/pocket/pocket.php b/plugins/pocket/pocket.php
deleted file mode 100644 (file)
index 3fc51dd..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-class Pocket extends Plugin {
-
-       private $link;
-       private $host;
-
-       function about() {
-               return array(1.0,
-                       "Share article on Pocket (formerly Read It Later)",
-                       "?");
-       }
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-
-               $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
-       }
-
-       function get_js() {
-               return file_get_contents(dirname(__FILE__) . "/pocket.js");
-       }
-
-       function hook_article_button($line) {
-               $article_id = $line["id"];
-
-               $rv = "<img src=\"".theme_image($this->link, 'plugins/pocket/pocket.png')."\"
-                       class='tagsPic' style=\"cursor : pointer\"
-                       onclick=\"shareArticleToPocket($article_id)\"
-                       title='".__('Pocket')."'>";
-
-               return $rv;
-       }
-
-       function getInfo() {
-               $id = db_escape_string($_REQUEST['id']);
-
-               $result = db_query($this->link, "SELECT title, link
-                               FROM ttrss_entries, ttrss_user_entries
-                               WHERE id = '$id' AND ref_id = id AND owner_uid = " .$_SESSION['uid']);
-
-               if (db_num_rows($result) != 0) {
-                       $title = truncate_string(strip_tags(db_fetch_result($result, 0, 'title')),
-                               100, '...');
-                       $article_link = db_fetch_result($result, 0, 'link');
-               }
-
-               print json_encode(array("title" => $title, "link" => $article_link,
-                               "id" => $id));
-       }
-
-
-}
-?>
diff --git a/plugins/share/init.php b/plugins/share/init.php
new file mode 100644 (file)
index 0000000..e115184
--- /dev/null
@@ -0,0 +1,74 @@
+<?php
+class Share extends Plugin {
+       private $link;
+       private $host;
+
+       function about() {
+               return array(1.0,
+                       "Share article by unique URL",
+                       "fox");
+       }
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
+       }
+
+       function get_js() {
+               return file_get_contents(dirname(__FILE__) . "/share.js");
+       }
+
+       function hook_article_button($line) {
+               return "<img src=\"".theme_image($this->link, 'plugins/share/share.png')."\"
+                       class='tagsPic' style=\"cursor : pointer\"
+                       onclick=\"shareArticle(".$line['int_id'].")\"
+                       title='".__('Share by URL')."'>";
+       }
+
+       function shareArticle() {
+               $param = db_escape_string($_REQUEST['param']);
+
+               $result = db_query($this->link, "SELECT uuid, ref_id FROM ttrss_user_entries WHERE int_id = '$param'
+                       AND owner_uid = " . $_SESSION['uid']);
+
+               if (db_num_rows($result) == 0) {
+                       print "Article not found.";
+               } else {
+
+                       $uuid = db_fetch_result($result, 0, "uuid");
+                       $ref_id = db_fetch_result($result, 0, "ref_id");
+
+                       if (!$uuid) {
+                               $uuid = db_escape_string(sha1(uniqid(rand(), true)));
+                               db_query($this->link, "UPDATE ttrss_user_entries SET uuid = '$uuid' WHERE int_id = '$param'
+                                       AND owner_uid = " . $_SESSION['uid']);
+                       }
+
+                       print __("You can share this article by the following unique URL:");
+
+                       $url_path = get_self_url_prefix();
+                       $url_path .= "/public.php?op=share&key=$uuid";
+
+                       print "<div class=\"tagCloudContainer\">";
+                       print "<a id='pub_opml_url' href='$url_path' target='_blank'>$url_path</a>";
+                       print "</div>";
+
+                       /* if (!label_find_id($this->link, __('Shared'), $_SESSION["uid"]))
+                               label_create($this->link, __('Shared'), $_SESSION["uid"]);
+
+                       label_add_article($this->link, $ref_id, __('Shared'), $_SESSION['uid']); */
+               }
+
+               print "<div align='center'>";
+
+               print "<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('shareArticleDlg').hide()\">".
+                       __('Close this window')."</button>";
+
+               print "</div>";
+       }
+
+
+}
+?>
diff --git a/plugins/share/share.php b/plugins/share/share.php
deleted file mode 100644 (file)
index e115184..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-class Share extends Plugin {
-       private $link;
-       private $host;
-
-       function about() {
-               return array(1.0,
-                       "Share article by unique URL",
-                       "fox");
-       }
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-
-               $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
-       }
-
-       function get_js() {
-               return file_get_contents(dirname(__FILE__) . "/share.js");
-       }
-
-       function hook_article_button($line) {
-               return "<img src=\"".theme_image($this->link, 'plugins/share/share.png')."\"
-                       class='tagsPic' style=\"cursor : pointer\"
-                       onclick=\"shareArticle(".$line['int_id'].")\"
-                       title='".__('Share by URL')."'>";
-       }
-
-       function shareArticle() {
-               $param = db_escape_string($_REQUEST['param']);
-
-               $result = db_query($this->link, "SELECT uuid, ref_id FROM ttrss_user_entries WHERE int_id = '$param'
-                       AND owner_uid = " . $_SESSION['uid']);
-
-               if (db_num_rows($result) == 0) {
-                       print "Article not found.";
-               } else {
-
-                       $uuid = db_fetch_result($result, 0, "uuid");
-                       $ref_id = db_fetch_result($result, 0, "ref_id");
-
-                       if (!$uuid) {
-                               $uuid = db_escape_string(sha1(uniqid(rand(), true)));
-                               db_query($this->link, "UPDATE ttrss_user_entries SET uuid = '$uuid' WHERE int_id = '$param'
-                                       AND owner_uid = " . $_SESSION['uid']);
-                       }
-
-                       print __("You can share this article by the following unique URL:");
-
-                       $url_path = get_self_url_prefix();
-                       $url_path .= "/public.php?op=share&key=$uuid";
-
-                       print "<div class=\"tagCloudContainer\">";
-                       print "<a id='pub_opml_url' href='$url_path' target='_blank'>$url_path</a>";
-                       print "</div>";
-
-                       /* if (!label_find_id($this->link, __('Shared'), $_SESSION["uid"]))
-                               label_create($this->link, __('Shared'), $_SESSION["uid"]);
-
-                       label_add_article($this->link, $ref_id, __('Shared'), $_SESSION['uid']); */
-               }
-
-               print "<div align='center'>";
-
-               print "<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('shareArticleDlg').hide()\">".
-                       __('Close this window')."</button>";
-
-               print "</div>";
-       }
-
-
-}
-?>
diff --git a/plugins/swap_jk/init.php b/plugins/swap_jk/init.php
new file mode 100644 (file)
index 0000000..34b09bd
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+class Swap_JK extends Plugin {
+
+       private $link;
+       private $host;
+
+       function about() {
+               return array(1.0,
+                       "Swap j and k hotkeys (for vi brethren)",
+                       "fox");
+       }
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_hook($host::HOOK_HOTKEY_MAP, $this);
+       }
+
+       function hook_hotkey_map($hotkeys) {
+
+               $hotkeys["j"] = "next_feed";
+               $hotkeys["k"] = "prev_feed";
+
+               return $hotkeys;
+
+       }
+}
+?>
diff --git a/plugins/swap_jk/swap_jk.php b/plugins/swap_jk/swap_jk.php
deleted file mode 100644 (file)
index 34b09bd..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-class Swap_JK extends Plugin {
-
-       private $link;
-       private $host;
-
-       function about() {
-               return array(1.0,
-                       "Swap j and k hotkeys (for vi brethren)",
-                       "fox");
-       }
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-
-               $host->add_hook($host::HOOK_HOTKEY_MAP, $this);
-       }
-
-       function hook_hotkey_map($hotkeys) {
-
-               $hotkeys["j"] = "next_feed";
-               $hotkeys["k"] = "prev_feed";
-
-               return $hotkeys;
-
-       }
-}
-?>
diff --git a/plugins/updater/init.php b/plugins/updater/init.php
new file mode 100644 (file)
index 0000000..b089e81
--- /dev/null
@@ -0,0 +1,337 @@
+<?php
+class Updater extends Plugin {
+
+       private $link;
+       private $host;
+
+       function about() {
+               return array(1.0,
+                       "Updates tt-rss installation to latest version.",
+                       "fox",
+                       true);
+       }
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_hook($host::HOOK_PREFS_TAB, $this);
+
+               $host->add_command("update-self",
+                       "update tt-rss installation to latest version",
+                       $this);
+       }
+
+       function update_self_step($link, $step, $params, $force = false) {
+               // __FILE__ is in plugins/updater so we need to go one level up
+               $work_dir = dirname(dirname(dirname(__FILE__)));
+               $parent_dir = dirname($work_dir);
+
+               if (!chdir($work_dir)) {
+                       array_push($log, "Unable to change to work directory: $work_dir");
+                       $stop = true; break;
+               }
+
+               $stop = false;
+               $log = array();
+               if (!is_array($params)) $params = array();
+
+               switch ($step) {
+               case 0:
+                       array_push($log, "Work directory: $work_dir");
+
+                       if (!is_writable($work_dir) && !is_writable("$parent_dir")) {
+                               $user = posix_getpwuid(posix_geteuid());
+                               $user = $user["name"];
+                               array_push($log, "Both tt-rss and parent directories should be writable as current user ($user).");
+                               $stop = true; break;
+                       }
+
+                       if (!file_exists("$work_dir/config.php") || !file_exists("$work_dir/include/sanity_check.php")) {
+                               array_push($log, "Work directory $work_dir doesn't look like tt-rss installation.");
+                               $stop = true; break;
+                       }
+
+                       if (!is_writable(sys_get_temp_dir())) {
+                               array_push($log, "System temporary directory should be writable as current user.");
+                               $stop = true; break;
+                       }
+
+                       array_push($log, "Checking for tar...");
+
+                       $system_rc = 0;
+                       system("tar --version >/dev/null", $system_rc);
+
+                       if ($system_rc != 0) {
+                               array_push($log, "Could not run tar executable (RC=$system_rc).");
+                               $stop = true; break;
+                       }
+
+                       array_push($log, "Checking for gunzip...");
+
+                       $system_rc = 0;
+                       system("gunzip --version >/dev/null", $system_rc);
+
+                       if ($system_rc != 0) {
+                               array_push($log, "Could not run gunzip executable (RC=$system_rc).");
+                               $stop = true; break;
+                       }
+
+
+                       array_push($log, "Checking for latest version...");
+
+                       $version_info = json_decode(fetch_file_contents("http://tt-rss.org/version.php"),
+                               true);
+
+                       if (!is_array($version_info)) {
+                               array_push($log, "Unable to fetch version information.");
+                               $stop = true; break;
+                       }
+
+                       $target_version = $version_info["version"];
+                       $target_dir = "$parent_dir/tt-rss-$target_version";
+
+                       array_push($log, "Target version: $target_version");
+                       $params["target_version"] = $target_version;
+
+                       if (version_compare(VERSION, $target_version) != -1 && !$force) {
+                               array_push($log, "Your Tiny Tiny RSS installation is up to date.");
+                               $stop = true; break;
+                       }
+
+                       if (file_exists($target_dir)) {
+                               array_push($log, "Target directory $target_dir already exists.");
+                               $stop = true; break;
+                       }
+
+                       break;
+               case 1:
+                       $target_version = $params["target_version"];
+
+                       array_push($log, "Downloading checksums...");
+                       $md5sum_data = fetch_file_contents("http://tt-rss.org/download/md5sum.txt");
+
+                       if (!$md5sum_data) {
+                               array_push($log, "Could not download checksums.");
+                               $stop = true; break;
+                       }
+
+                       $md5sum_data = explode("\n", $md5sum_data);
+
+                       foreach ($md5sum_data as $line) {
+                               $pair = explode("  ", $line);
+
+                               if ($pair[1] == "tt-rss-$target_version.tar.gz") {
+                                       $target_md5sum = $pair[0];
+                                       break;
+                               }
+                       }
+
+                       if (!$target_md5sum) {
+                               array_push($log, "Unable to locate checksum for target version.");
+                               $stop = true; break;
+                       }
+
+                       $params["target_md5sum"] = $target_md5sum;
+
+                       break;
+               case 2:
+                       $target_version = $params["target_version"];
+                       $target_md5sum = $params["target_md5sum"];
+
+                       array_push($log, "Downloading distribution tarball...");
+
+                       $tarball_url = "http://tt-rss.org/download/tt-rss-$target_version.tar.gz";
+                       $data = fetch_file_contents($tarball_url);
+
+                       if (!$data) {
+                               array_push($log, "Could not download distribution tarball ($tarball_url).");
+                               $stop = true; break;
+                       }
+
+                       array_push($log, "Verifying tarball checksum...");
+
+                       $test_md5sum = md5($data);
+
+                       if ($test_md5sum != $target_md5sum) {
+                               array_push($log, "Downloaded checksum doesn't match (got $test_md5sum, expected $target_md5sum).");
+                               $stop = true; break;
+                       }
+
+                       $tmp_file = tempnam(sys_get_temp_dir(), 'tt-rss');
+                       array_push($log, "Saving download to $tmp_file");
+
+                       if (!file_put_contents($tmp_file, $data)) {
+                               array_push($log, "Unable to save download.");
+                               $stop = true; break;
+                       }
+
+                       $params["tmp_file"] = $tmp_file;
+
+                       break;
+               case 3:
+                       $tmp_file = $params["tmp_file"];
+                       $target_version = $params["target_version"];
+
+                       if (!chdir($parent_dir)) {
+                               array_push($log, "Unable to change into parent directory.");
+                               $stop = true; break;
+                       }
+
+                       $old_dir = tmpdirname($parent_dir, "tt-rss-old");
+
+                       array_push($log, "Renaming tt-rss directory to ".basename($old_dir));
+                       if (!rename($work_dir, $old_dir)) {
+                               array_push($log, "Unable to rename tt-rss directory.");
+                               $stop = true; break;
+                       }
+
+                       array_push($log, "Extracting tarball...");
+                       system("tar zxf $tmp_file", $system_rc);
+
+                       if ($system_rc != 0) {
+                               array_push($log, "Error while extracting tarball (RC=$system_rc).");
+                               $stop = true; break;
+                       }
+
+                       $target_dir = "$parent_dir/tt-rss-$target_version";
+
+                       array_push($log, "Renaming target directory...");
+                       if (!rename($target_dir, $work_dir)) {
+                               array_push($log, "Unable to rename target directory.");
+                               $stop = true; break;
+                       }
+
+                       if (!chdir($work_dir)) {
+                               array_push($log, "Unable to change to work directory: $work_dir");
+                               $stop = true; break;
+                       }
+
+                       array_push($log, "Copying config.php...");
+                       if (!copy("$old_dir/config.php", "$work_dir/config.php")) {
+                               array_push($log, "Unable to copy config.php to $work_dir.");
+                               $stop = true; break;
+                       }
+
+                       array_push($log, "Cleaning up...");
+                       unlink($tmp_file);
+
+                       array_push($log, "Fixing permissions...");
+
+                       $directories = array(
+                               CACHE_DIR,
+                               CACHE_DIR . "/export",
+                               CACHE_DIR . "/images",
+                               CACHE_DIR . "/simplepie",
+                               ICONS_DIR,
+                               LOCK_DIRECTORY);
+
+                       foreach ($directories as $dir) {
+                               array_push($log, "-> $dir");
+                               chmod($dir, 0777);
+                       }
+
+                       array_push($log, "Upgrade completed.");
+                       array_push($log, "Your old tt-rss directory is saved at $old_dir. ".
+                               "Please migrate locally modified files (if any) and remove it.");
+                       array_push($log, "You might need to re-enter current directory in shell to see new files.");
+
+                       $stop = true;
+                       break;
+               default:
+                       $stop = true;
+               }
+
+               return array("step" => $step, "stop" => $stop, "params" => $params, "log" => $log);
+       }
+
+       function update_self_cli($link, $force = false) {
+               $step = 0;
+               $stop = false;
+               $params = array();
+
+               while (!$stop) {
+                       $rc = $this->update_self_step($link, $step, $params, $force);
+
+                       $params = $rc['params'];
+                       $stop = $rc['stop'];
+
+                       foreach ($rc['log'] as $line) {
+                               _debug($line);
+                       }
+                       ++$step;
+               }
+       }
+
+       function update_self($args) {
+               _debug("Warning: self-updating is experimental. Use at your own risk.");
+               _debug("Please backup your tt-rss directory before continuing. Your database will not be modified.");
+               _debug("Type 'yes' to continue.");
+
+               if (read_stdin() != 'yes')
+                       exit;
+
+               $this->update_self_cli($link, in_array("-force", $args));
+       }
+
+       function get_prefs_js() {
+               return file_get_contents(dirname(__FILE__) . "/updater.js");
+       }
+
+       function hook_prefs_tab($args) {
+               if ($args != "prefPrefs") return;
+
+               if (($_SESSION["access_level"] >= 10 || SINGLE_USER_MODE) && CHECK_FOR_NEW_VERSION) {
+                       print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__('Update Tiny Tiny RSS')."\">";
+
+                       if ($_SESSION["pref_last_version_check"] + 86400 + rand(-1000, 1000) < time()) {
+                               $_SESSION["version_data"] = @check_for_update($this->link);
+                               $_SESSION["pref_last_version_check"] = time();
+                       }
+
+                       if (is_array($_SESSION["version_data"])) {
+                               $version = $_SESSION["version_data"]["version"];
+                               print_notice(T_sprintf("New version of Tiny Tiny RSS is available (%s).", "<b>$version</b>"));
+
+                               print "<p><button dojoType=\"dijit.form.Button\" onclick=\"return updateSelf()\">".
+                                       __('Update Tiny Tiny RSS')."</button></p>";
+
+                       } else {
+                               print_notice(__("Your Tiny Tiny RSS installation is up to date."));
+                       }
+
+                       print "</div>"; #pane
+               }
+
+       function updateSelf() {
+               print "<form style='display : block' name='self_update_form' id='self_update_form'>";
+
+               print "<div class='error'>".__("Do not close this dialog until updating is finished. Backup your tt-rss directory before continuing.")."</div>";
+
+               print "<ul class='selfUpdateList' id='self_update_log'>";
+               print "<li>" . __("Ready to update.") . "</li>";
+               print "</ul>";
+
+               print "<div class='dlgButtons'>";
+               print "<button id=\"self_update_start_btn\" dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('updateSelfDlg').start()\" >".
+                       __("Start update")."</button>";
+               print "<button id=\"self_update_stop_btn\" onclick=\"return dijit.byId('updateSelfDlg').close()\" dojoType=\"dijit.form.Button\">".
+                       __("Close this window")."</button>";
+               print "</div>";
+               print "</form>";
+       }
+
+       function performUpdate() {
+               $step = (int) $_REQUEST["step"];
+               $params = json_decode($_REQUEST["params"], true);
+               $force = (bool) $_REQUEST["force"];
+
+               if (($_SESSION["access_level"] >= 10 || SINGLE_USER_MODE) && CHECK_FOR_NEW_VERSION) {
+                       print   json_encode($this->update_self_step($this->link, $step, $params, $force));
+               }
+       }
+
+
+       }
+}
+?>
diff --git a/plugins/updater/updater.php b/plugins/updater/updater.php
deleted file mode 100644 (file)
index b089e81..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-<?php
-class Updater extends Plugin {
-
-       private $link;
-       private $host;
-
-       function about() {
-               return array(1.0,
-                       "Updates tt-rss installation to latest version.",
-                       "fox",
-                       true);
-       }
-
-       function init($host) {
-               $this->link = $host->get_link();
-               $this->host = $host;
-
-               $host->add_hook($host::HOOK_PREFS_TAB, $this);
-
-               $host->add_command("update-self",
-                       "update tt-rss installation to latest version",
-                       $this);
-       }
-
-       function update_self_step($link, $step, $params, $force = false) {
-               // __FILE__ is in plugins/updater so we need to go one level up
-               $work_dir = dirname(dirname(dirname(__FILE__)));
-               $parent_dir = dirname($work_dir);
-
-               if (!chdir($work_dir)) {
-                       array_push($log, "Unable to change to work directory: $work_dir");
-                       $stop = true; break;
-               }
-
-               $stop = false;
-               $log = array();
-               if (!is_array($params)) $params = array();
-
-               switch ($step) {
-               case 0:
-                       array_push($log, "Work directory: $work_dir");
-
-                       if (!is_writable($work_dir) && !is_writable("$parent_dir")) {
-                               $user = posix_getpwuid(posix_geteuid());
-                               $user = $user["name"];
-                               array_push($log, "Both tt-rss and parent directories should be writable as current user ($user).");
-                               $stop = true; break;
-                       }
-
-                       if (!file_exists("$work_dir/config.php") || !file_exists("$work_dir/include/sanity_check.php")) {
-                               array_push($log, "Work directory $work_dir doesn't look like tt-rss installation.");
-                               $stop = true; break;
-                       }
-
-                       if (!is_writable(sys_get_temp_dir())) {
-                               array_push($log, "System temporary directory should be writable as current user.");
-                               $stop = true; break;
-                       }
-
-                       array_push($log, "Checking for tar...");
-
-                       $system_rc = 0;
-                       system("tar --version >/dev/null", $system_rc);
-
-                       if ($system_rc != 0) {
-                               array_push($log, "Could not run tar executable (RC=$system_rc).");
-                               $stop = true; break;
-                       }
-
-                       array_push($log, "Checking for gunzip...");
-
-                       $system_rc = 0;
-                       system("gunzip --version >/dev/null", $system_rc);
-
-                       if ($system_rc != 0) {
-                               array_push($log, "Could not run gunzip executable (RC=$system_rc).");
-                               $stop = true; break;
-                       }
-
-
-                       array_push($log, "Checking for latest version...");
-
-                       $version_info = json_decode(fetch_file_contents("http://tt-rss.org/version.php"),
-                               true);
-
-                       if (!is_array($version_info)) {
-                               array_push($log, "Unable to fetch version information.");
-                               $stop = true; break;
-                       }
-
-                       $target_version = $version_info["version"];
-                       $target_dir = "$parent_dir/tt-rss-$target_version";
-
-                       array_push($log, "Target version: $target_version");
-                       $params["target_version"] = $target_version;
-
-                       if (version_compare(VERSION, $target_version) != -1 && !$force) {
-                               array_push($log, "Your Tiny Tiny RSS installation is up to date.");
-                               $stop = true; break;
-                       }
-
-                       if (file_exists($target_dir)) {
-                               array_push($log, "Target directory $target_dir already exists.");
-                               $stop = true; break;
-                       }
-
-                       break;
-               case 1:
-                       $target_version = $params["target_version"];
-
-                       array_push($log, "Downloading checksums...");
-                       $md5sum_data = fetch_file_contents("http://tt-rss.org/download/md5sum.txt");
-
-                       if (!$md5sum_data) {
-                               array_push($log, "Could not download checksums.");
-                               $stop = true; break;
-                       }
-
-                       $md5sum_data = explode("\n", $md5sum_data);
-
-                       foreach ($md5sum_data as $line) {
-                               $pair = explode("  ", $line);
-
-                               if ($pair[1] == "tt-rss-$target_version.tar.gz") {
-                                       $target_md5sum = $pair[0];
-                                       break;
-                               }
-                       }
-
-                       if (!$target_md5sum) {
-                               array_push($log, "Unable to locate checksum for target version.");
-                               $stop = true; break;
-                       }
-
-                       $params["target_md5sum"] = $target_md5sum;
-
-                       break;
-               case 2:
-                       $target_version = $params["target_version"];
-                       $target_md5sum = $params["target_md5sum"];
-
-                       array_push($log, "Downloading distribution tarball...");
-
-                       $tarball_url = "http://tt-rss.org/download/tt-rss-$target_version.tar.gz";
-                       $data = fetch_file_contents($tarball_url);
-
-                       if (!$data) {
-                               array_push($log, "Could not download distribution tarball ($tarball_url).");
-                               $stop = true; break;
-                       }
-
-                       array_push($log, "Verifying tarball checksum...");
-
-                       $test_md5sum = md5($data);
-
-                       if ($test_md5sum != $target_md5sum) {
-                               array_push($log, "Downloaded checksum doesn't match (got $test_md5sum, expected $target_md5sum).");
-                               $stop = true; break;
-                       }
-
-                       $tmp_file = tempnam(sys_get_temp_dir(), 'tt-rss');
-                       array_push($log, "Saving download to $tmp_file");
-
-                       if (!file_put_contents($tmp_file, $data)) {
-                               array_push($log, "Unable to save download.");
-                               $stop = true; break;
-                       }
-
-                       $params["tmp_file"] = $tmp_file;
-
-                       break;
-               case 3:
-                       $tmp_file = $params["tmp_file"];
-                       $target_version = $params["target_version"];
-
-                       if (!chdir($parent_dir)) {
-                               array_push($log, "Unable to change into parent directory.");
-                               $stop = true; break;
-                       }
-
-                       $old_dir = tmpdirname($parent_dir, "tt-rss-old");
-
-                       array_push($log, "Renaming tt-rss directory to ".basename($old_dir));
-                       if (!rename($work_dir, $old_dir)) {
-                               array_push($log, "Unable to rename tt-rss directory.");
-                               $stop = true; break;
-                       }
-
-                       array_push($log, "Extracting tarball...");
-                       system("tar zxf $tmp_file", $system_rc);
-
-                       if ($system_rc != 0) {
-                               array_push($log, "Error while extracting tarball (RC=$system_rc).");
-                               $stop = true; break;
-                       }
-
-                       $target_dir = "$parent_dir/tt-rss-$target_version";
-
-                       array_push($log, "Renaming target directory...");
-                       if (!rename($target_dir, $work_dir)) {
-                               array_push($log, "Unable to rename target directory.");
-                               $stop = true; break;
-                       }
-
-                       if (!chdir($work_dir)) {
-                               array_push($log, "Unable to change to work directory: $work_dir");
-                               $stop = true; break;
-                       }
-
-                       array_push($log, "Copying config.php...");
-                       if (!copy("$old_dir/config.php", "$work_dir/config.php")) {
-                               array_push($log, "Unable to copy config.php to $work_dir.");
-                               $stop = true; break;
-                       }
-
-                       array_push($log, "Cleaning up...");
-                       unlink($tmp_file);
-
-                       array_push($log, "Fixing permissions...");
-
-                       $directories = array(
-                               CACHE_DIR,
-                               CACHE_DIR . "/export",
-                               CACHE_DIR . "/images",
-                               CACHE_DIR . "/simplepie",
-                               ICONS_DIR,
-                               LOCK_DIRECTORY);
-
-                       foreach ($directories as $dir) {
-                               array_push($log, "-> $dir");
-                               chmod($dir, 0777);
-                       }
-
-                       array_push($log, "Upgrade completed.");
-                       array_push($log, "Your old tt-rss directory is saved at $old_dir. ".
-                               "Please migrate locally modified files (if any) and remove it.");
-                       array_push($log, "You might need to re-enter current directory in shell to see new files.");
-
-                       $stop = true;
-                       break;
-               default:
-                       $stop = true;
-               }
-
-               return array("step" => $step, "stop" => $stop, "params" => $params, "log" => $log);
-       }
-
-       function update_self_cli($link, $force = false) {
-               $step = 0;
-               $stop = false;
-               $params = array();
-
-               while (!$stop) {
-                       $rc = $this->update_self_step($link, $step, $params, $force);
-
-                       $params = $rc['params'];
-                       $stop = $rc['stop'];
-
-                       foreach ($rc['log'] as $line) {
-                               _debug($line);
-                       }
-                       ++$step;
-               }
-       }
-
-       function update_self($args) {
-               _debug("Warning: self-updating is experimental. Use at your own risk.");
-               _debug("Please backup your tt-rss directory before continuing. Your database will not be modified.");
-               _debug("Type 'yes' to continue.");
-
-               if (read_stdin() != 'yes')
-                       exit;
-
-               $this->update_self_cli($link, in_array("-force", $args));
-       }
-
-       function get_prefs_js() {
-               return file_get_contents(dirname(__FILE__) . "/updater.js");
-       }
-
-       function hook_prefs_tab($args) {
-               if ($args != "prefPrefs") return;
-
-               if (($_SESSION["access_level"] >= 10 || SINGLE_USER_MODE) && CHECK_FOR_NEW_VERSION) {
-                       print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__('Update Tiny Tiny RSS')."\">";
-
-                       if ($_SESSION["pref_last_version_check"] + 86400 + rand(-1000, 1000) < time()) {
-                               $_SESSION["version_data"] = @check_for_update($this->link);
-                               $_SESSION["pref_last_version_check"] = time();
-                       }
-
-                       if (is_array($_SESSION["version_data"])) {
-                               $version = $_SESSION["version_data"]["version"];
-                               print_notice(T_sprintf("New version of Tiny Tiny RSS is available (%s).", "<b>$version</b>"));
-
-                               print "<p><button dojoType=\"dijit.form.Button\" onclick=\"return updateSelf()\">".
-                                       __('Update Tiny Tiny RSS')."</button></p>";
-
-                       } else {
-                               print_notice(__("Your Tiny Tiny RSS installation is up to date."));
-                       }
-
-                       print "</div>"; #pane
-               }
-
-       function updateSelf() {
-               print "<form style='display : block' name='self_update_form' id='self_update_form'>";
-
-               print "<div class='error'>".__("Do not close this dialog until updating is finished. Backup your tt-rss directory before continuing.")."</div>";
-
-               print "<ul class='selfUpdateList' id='self_update_log'>";
-               print "<li>" . __("Ready to update.") . "</li>";
-               print "</ul>";
-
-               print "<div class='dlgButtons'>";
-               print "<button id=\"self_update_start_btn\" dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('updateSelfDlg').start()\" >".
-                       __("Start update")."</button>";
-               print "<button id=\"self_update_stop_btn\" onclick=\"return dijit.byId('updateSelfDlg').close()\" dojoType=\"dijit.form.Button\">".
-                       __("Close this window")."</button>";
-               print "</div>";
-               print "</form>";
-       }
-
-       function performUpdate() {
-               $step = (int) $_REQUEST["step"];
-               $params = json_decode($_REQUEST["params"], true);
-               $force = (bool) $_REQUEST["force"];
-
-               if (($_SESSION["access_level"] >= 10 || SINGLE_USER_MODE) && CHECK_FOR_NEW_VERSION) {
-                       print   json_encode($this->update_self_step($this->link, $step, $params, $force));
-               }
-       }
-
-
-       }
-}
-?>