]> git.wh0rd.org Git - tt-rss.git/commitdiff
add instances plugin
authorAndrew Dolgov <fox@fakecake.org>
Sun, 23 Dec 2012 19:36:07 +0000 (23:36 +0400)
committerAndrew Dolgov <fox@fakecake.org>
Sun, 23 Dec 2012 19:36:07 +0000 (23:36 +0400)
classes/pluginhost.php
classes/pref/instances.php [deleted file]
js/prefs.js
plugins/example_routing/example_routing.php
plugins/instances/README.txt [new file with mode: 0644]
plugins/instances/instances.js [new file with mode: 0644]
plugins/instances/instances.php [new file with mode: 0644]
prefs.php

index b28d2511d7423c391d2d649e77fba41bce0a2295..46415bd214874b18de66ebf37e9c153f9070d85d 100644 (file)
@@ -9,6 +9,7 @@ class PluginHost {
        const HOOK_ARTICLE_FILTER = 2;
        const HOOK_PREFS_TAB = 3;
        const HOOK_PREFS_SECTION = 4;
+       const HOOK_PREFS_TABS = 5;
 
        function __construct($link) {
                $this->link = $link;
@@ -77,7 +78,7 @@ class PluginHost {
        }
 
        function add_handler($handler, $method, $sender) {
-               $handler = strtolower($handler);
+               $handler = str_replace("-", "_", strtolower($handler));
                $method = strtolower($method);
 
                if (!is_array($this->handlers[$handler])) {
@@ -88,18 +89,22 @@ class PluginHost {
        }
 
        function del_handler($handler, $method) {
-               $handler = strtolower($handler);
+               $handler = str_replace("-", "_", strtolower($handler));
                $method = strtolower($method);
 
                unset($this->handlers[$handler][$method]);
        }
 
        function lookup_handler($handler, $method) {
-               $handler = strtolower($handler);
+               $handler = str_replace("-", "_", strtolower($handler));
                $method = strtolower($method);
 
                if (is_array($this->handlers[$handler])) {
-                       return $this->handlers[$handler][$method];
+                       if (isset($this->handlers[$handler]["*"])) {
+                               return $this->handlers[$handler]["*"];
+                       } else {
+                               return $this->handlers[$handler][$method];
+                       }
                }
 
                return false;
diff --git a/classes/pref/instances.php b/classes/pref/instances.php
deleted file mode 100644 (file)
index 763bb49..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-<?php
-class Pref_Instances extends Handler_Protected {
-
-       private $status_codes = array(
-               0       => "Connection failed",
-               1       => "Success",
-               2       => "Invalid object received",
-               16      => "Access denied" );
-
-       function csrf_ignore($method) {
-               $csrf_ignored = array("index", "edit");
-
-               return array_search($method, $csrf_ignored) !== false;
-       }
-
-       function before($method) {
-               if (parent::before($method)) {
-                       if ($_SESSION["access_level"] < 10) {
-                               print __("Your access level is insufficient to open this tab.");
-                               return false;
-                       }
-                       return true;
-               }
-               return false;
-       }
-
-       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
-
-       }
-}
-?>
index 51d8412fc848a15ba755c433b697ed656c224763..4687c60bb6ae2572536c094ad178d557c5c9f81a 100644 (file)
@@ -24,15 +24,6 @@ function updateFeedList(sort_key) {
                } });
 }
 
-function updateInstanceList(sort_key) {
-       new Ajax.Request("backend.php", {
-               parameters: "?op=pref-instances&sort=" + param_escape(sort_key),
-               onComplete: function(transport) {
-                       dijit.byId('instanceConfigTab').attr('content', transport.responseText);
-                       selectTab("instanceConfig", true);
-                       notify("");
-               } });
-}
 
 function updateUsersList(sort_key) {
        try {
@@ -1891,162 +1882,6 @@ function insertSSLserial(value) {
        }
 }
 
-function getSelectedInstances() {
-       return getSelectedTableRowIds("prefInstanceList");
-}
-
-function addInstance() {
-       try {
-               var query = "backend.php?op=dlg&method=addInstance";
-
-               if (dijit.byId("instanceAddDlg"))
-                       dijit.byId("instanceAddDlg").destroyRecursive();
-
-               dialog = new dijit.Dialog({
-                       id: "instanceAddDlg",
-                       title: __("Link Instance"),
-                       style: "width: 600px",
-                       regenKey: function() {
-                               new Ajax.Request("backend.php", {
-                                       parameters: "?op=rpc&method=genHash",
-                                       onComplete: function(transport) {
-                                               var reply = JSON.parse(transport.responseText);
-                                               if (reply)
-                                                       dijit.byId('instance_add_key').attr('value', reply.hash);
-
-                                       } });
-                       },
-                       execute: function() {
-                               if (this.validate()) {
-                                       console.warn(dojo.objectToQuery(this.attr('value')));
-
-                                       notify_progress('Saving data...', true);
-                                       new Ajax.Request("backend.php", {
-                                               parameters: dojo.objectToQuery(this.attr('value')),
-                                               onComplete: function(transport) {
-                                                       dialog.hide();
-                                                       notify('');
-                                                       updateInstanceList();
-                                       } });
-                               }
-                       },
-                       href: query,
-               });
-
-               dialog.show();
-
-       } catch (e) {
-               exception_error("addInstance", e);
-       }
-}
-
-function editInstance(id, event) {
-       try {
-               if (!event || !event.ctrlKey) {
-
-               selectTableRows('prefInstanceList', 'none');
-               selectTableRowById('LIRR-'+id, 'LICHK-'+id, true);
-
-               var query = "backend.php?op=pref-instances&method=edit&id=" +
-                       param_escape(id);
-
-               if (dijit.byId("instanceEditDlg"))
-                       dijit.byId("instanceEditDlg").destroyRecursive();
-
-               dialog = new dijit.Dialog({
-                       id: "instanceEditDlg",
-                       title: __("Edit Instance"),
-                       style: "width: 600px",
-                       regenKey: function() {
-                               new Ajax.Request("backend.php", {
-                                       parameters: "?op=rpc&method=genHash",
-                                       onComplete: function(transport) {
-                                               var reply = JSON.parse(transport.responseText);
-                                               if (reply)
-                                                       dijit.byId('instance_edit_key').attr('value', reply.hash);
-
-                                       } });
-                       },
-                       execute: function() {
-                               if (this.validate()) {
-//                                     console.warn(dojo.objectToQuery(this.attr('value')));
-
-                                       notify_progress('Saving data...', true);
-                                       new Ajax.Request("backend.php", {
-                                               parameters: dojo.objectToQuery(this.attr('value')),
-                                               onComplete: function(transport) {
-                                                       dialog.hide();
-                                                       notify('');
-                                                       updateInstanceList();
-                                       } });
-                               }
-                       },
-                       href: query,
-               });
-
-               dialog.show();
-
-               } else if (event.ctrlKey) {
-                       var cb = $('LICHK-' + id);
-                       cb.checked = !cb.checked;
-                       toggleSelectRow(cb);
-               }
-
-
-       } catch (e) {
-               exception_error("editInstance", e);
-       }
-}
-
-function removeSelectedInstances() {
-       try {
-               var sel_rows = getSelectedInstances();
-
-               if (sel_rows.length > 0) {
-
-                       var ok = confirm(__("Remove selected instances?"));
-
-                       if (ok) {
-                               notify_progress("Removing selected instances...");
-
-                               var query = "?op=pref-instances&method=remove&ids="+
-                                       param_escape(sel_rows.toString());
-
-                               new Ajax.Request("backend.php", {
-                                       parameters: query,
-                                       onComplete: function(transport) {
-                                               notify('');
-                                               updateInstanceList();
-                                       } });
-                       }
-
-               } else {
-                       alert(__("No instances are selected."));
-               }
-
-       } catch (e) {
-               exception_error("removeInstance", e);
-       }
-}
-
-function editSelectedInstance() {
-       var rows = getSelectedInstances();
-
-       if (rows.length == 0) {
-               alert(__("No instances are selected."));
-               return;
-       }
-
-       if (rows.length > 1) {
-               alert(__("Please select only one instance."));
-               return;
-       }
-
-       notify("");
-
-       editInstance(rows[0]);
-}
-
 function showHelp() {
        try {
                new Ajax.Request("backend.php", {
index a5c4e61397227714276a5031915fe0a21a0bd93e..c8d352ac80dcaa8003df3df0f90bd04b99ee0ce5 100644 (file)
@@ -9,7 +9,8 @@ class Example_Routing extends Plugin implements IHandler {
        // 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.
+       // Any system method may be masked by plugins. You can mask
+       // entire handler by supplying "*" instead of a method name.
 
        private $link;
        private $host;
diff --git a/plugins/instances/README.txt b/plugins/instances/README.txt
new file mode 100644 (file)
index 0000000..d4e4039
--- /dev/null
@@ -0,0 +1 @@
+Adds support for linking other tt-rss instances
diff --git a/plugins/instances/instances.js b/plugins/instances/instances.js
new file mode 100644 (file)
index 0000000..8321389
--- /dev/null
@@ -0,0 +1,169 @@
+function addInstance() {
+       try {
+               var query = "backend.php?op=dlg&method=addInstance";
+
+               if (dijit.byId("instanceAddDlg"))
+                       dijit.byId("instanceAddDlg").destroyRecursive();
+
+               dialog = new dijit.Dialog({
+                       id: "instanceAddDlg",
+                       title: __("Link Instance"),
+                       style: "width: 600px",
+                       regenKey: function() {
+                               new Ajax.Request("backend.php", {
+                                       parameters: "?op=rpc&method=genHash",
+                                       onComplete: function(transport) {
+                                               var reply = JSON.parse(transport.responseText);
+                                               if (reply)
+                                                       dijit.byId('instance_add_key').attr('value', reply.hash);
+
+                                       } });
+                       },
+                       execute: function() {
+                               if (this.validate()) {
+                                       console.warn(dojo.objectToQuery(this.attr('value')));
+
+                                       notify_progress('Saving data...', true);
+                                       new Ajax.Request("backend.php", {
+                                               parameters: dojo.objectToQuery(this.attr('value')),
+                                               onComplete: function(transport) {
+                                                       dialog.hide();
+                                                       notify('');
+                                                       updateInstanceList();
+                                       } });
+                               }
+                       },
+                       href: query,
+               });
+
+               dialog.show();
+
+       } catch (e) {
+               exception_error("addInstance", e);
+       }
+}
+
+// *** INS ***
+
+function updateInstanceList(sort_key) {
+       new Ajax.Request("backend.php", {
+               parameters: "?op=pref-instances&sort=" + param_escape(sort_key),
+               onComplete: function(transport) {
+                       dijit.byId('instanceConfigTab').attr('content', transport.responseText);
+                       selectTab("instanceConfig", true);
+                       notify("");
+               } });
+}
+
+function editInstance(id, event) {
+       try {
+               if (!event || !event.ctrlKey) {
+
+               selectTableRows('prefInstanceList', 'none');
+               selectTableRowById('LIRR-'+id, 'LICHK-'+id, true);
+
+               var query = "backend.php?op=pref-instances&method=edit&id=" +
+                       param_escape(id);
+
+               if (dijit.byId("instanceEditDlg"))
+                       dijit.byId("instanceEditDlg").destroyRecursive();
+
+               dialog = new dijit.Dialog({
+                       id: "instanceEditDlg",
+                       title: __("Edit Instance"),
+                       style: "width: 600px",
+                       regenKey: function() {
+                               new Ajax.Request("backend.php", {
+                                       parameters: "?op=rpc&method=genHash",
+                                       onComplete: function(transport) {
+                                               var reply = JSON.parse(transport.responseText);
+                                               if (reply)
+                                                       dijit.byId('instance_edit_key').attr('value', reply.hash);
+
+                                       } });
+                       },
+                       execute: function() {
+                               if (this.validate()) {
+//                                     console.warn(dojo.objectToQuery(this.attr('value')));
+
+                                       notify_progress('Saving data...', true);
+                                       new Ajax.Request("backend.php", {
+                                               parameters: dojo.objectToQuery(this.attr('value')),
+                                               onComplete: function(transport) {
+                                                       dialog.hide();
+                                                       notify('');
+                                                       updateInstanceList();
+                                       } });
+                               }
+                       },
+                       href: query,
+               });
+
+               dialog.show();
+
+               } else if (event.ctrlKey) {
+                       var cb = $('LICHK-' + id);
+                       cb.checked = !cb.checked;
+                       toggleSelectRow(cb);
+               }
+
+
+       } catch (e) {
+               exception_error("editInstance", e);
+       }
+}
+
+function removeSelectedInstances() {
+       try {
+               var sel_rows = getSelectedInstances();
+
+               if (sel_rows.length > 0) {
+
+                       var ok = confirm(__("Remove selected instances?"));
+
+                       if (ok) {
+                               notify_progress("Removing selected instances...");
+
+                               var query = "?op=pref-instances&method=remove&ids="+
+                                       param_escape(sel_rows.toString());
+
+                               new Ajax.Request("backend.php", {
+                                       parameters: query,
+                                       onComplete: function(transport) {
+                                               notify('');
+                                               updateInstanceList();
+                                       } });
+                       }
+
+               } else {
+                       alert(__("No instances are selected."));
+               }
+
+       } catch (e) {
+               exception_error("removeInstance", e);
+       }
+}
+
+function editSelectedInstance() {
+       var rows = getSelectedInstances();
+
+       if (rows.length == 0) {
+               alert(__("No instances are selected."));
+               return;
+       }
+
+       if (rows.length > 1) {
+               alert(__("Please select only one instance."));
+               return;
+       }
+
+       notify("");
+
+       editInstance(rows[0]);
+}
+
+function getSelectedInstances() {
+       return getSelectedTableRowIds("prefInstanceList");
+}
+
+
diff --git a/plugins/instances/instances.php b/plugins/instances/instances.php
new file mode 100644 (file)
index 0000000..c5d8067
--- /dev/null
@@ -0,0 +1,252 @@
+<?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 __construct($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+
+               $host->add_hook($host::HOOK_PREFS_TABS, $this);
+               $host->add_handler("pref-instances", "*", $this);
+       }
+
+       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
+
+       }
+
+}
+?>
+
index 74bcd4cc17d58a6168249a35b6df0c38c1c15cb1..8b554167371373fde337d2fc2a381906298addf1 100644 (file)
--- a/prefs.php
+++ b/prefs.php
                href="backend.php?op=pref-users"
                title="<?php echo __('Users') ?>"></div>
 <?php } ?>
-<?php 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 } ?>
-
+<?php
+       $pluginhost->run_hooks($pluginhost::HOOK_PREFS_TABS,
+               "hook_prefs_tabs", false);
+?>
 </div>
 
 <div id="footer" dojoType="dijit.layout.ContentPane" region="bottom">