]> git.wh0rd.org - tt-rss.git/commitdiff
experimental support for per-user plugins (bump schema)
authorAndrew Dolgov <fox@fakecake.org>
Mon, 24 Dec 2012 20:45:10 +0000 (00:45 +0400)
committerAndrew Dolgov <fox@fakecake.org>
Mon, 24 Dec 2012 20:45:10 +0000 (00:45 +0400)
16 files changed:
backend.php
classes/pluginhost.php
classes/pref/feeds.php
classes/pref/prefs.php
include/functions.php
plugins/digest/digest.php
plugins/example/example.php
plugins/example_feed/example_feed.php
plugins/example_routing/example_routing.php
plugins/instances/instances.php
plugins/updater/updater.php
prefs.php
schema/ttrss_schema_mysql.sql
schema/ttrss_schema_pgsql.sql
schema/versions/mysql/100.sql [new file with mode: 0644]
schema/versions/pgsql/100.sql [new file with mode: 0644]

index 66afb06c030ca59554100f0161a11321fb34a3a5..cc45b6a8513674f2923598a08180ad1bf4df23ca 100644 (file)
                authenticate_user($link, "admin", null);
        }
 
+       if ($_SESSION["uid"]) {
+               load_user_plugins($link, $_SESSION["uid"]);
+       }
+
        $purge_intervals = array(
                0  => __("Use default"),
                -1 => __("Never purge"),
index a637a52169773a0ffa520450168bb2179a055f04..d8df6db49a50addaedeae1759344141d55207064 100644 (file)
@@ -78,32 +78,45 @@ class PluginHost {
                        $class_file = strtolower(basename($class));
                        $file = dirname(__FILE__)."/../plugins/$class_file/$class_file.php";
 
-                       if (file_exists($file)) require_once $file;
+                       if (!isset($this->plugins[$class])) {
+                               if (file_exists($file)) require_once $file;
 
-                       if (class_exists($class) && is_subclass_of($class, "Plugin")) {
-                               $plugin = new $class($this);
+                               if (class_exists($class) && is_subclass_of($class, "Plugin")) {
+                                       $plugin = new $class($this);
 
-                               $this->register_plugin($class, $plugin);
+                                       $this->register_plugin($class, $plugin);
+                               }
                        }
                }
        }
 
+       function is_system($plugin) {
+               $about = $plugin->_about();
+
+               return @$about[3];
+       }
+
+       // only system plugins are allowed to modify routing
        function add_handler($handler, $method, $sender) {
                $handler = str_replace("-", "_", strtolower($handler));
                $method = strtolower($method);
 
-               if (!is_array($this->handlers[$handler])) {
-                       $this->handlers[$handler] = array();
-               }
+               if ($this->is_system($sender)) {
+                       if (!is_array($this->handlers[$handler])) {
+                               $this->handlers[$handler] = array();
+                       }
 
-               $this->handlers[$handler][$method] = $sender;
+                       $this->handlers[$handler][$method] = $sender;
+               }
        }
 
        function del_handler($handler, $method) {
                $handler = str_replace("-", "_", strtolower($handler));
                $method = strtolower($method);
 
-               unset($this->handlers[$handler][$method]);
+               if ($this->is_system($sender)) {
+                       unset($this->handlers[$handler][$method]);
+               }
        }
 
        function lookup_handler($handler, $method) {
@@ -121,17 +134,22 @@ class PluginHost {
                return false;
        }
 
+       // only system plugins are allowed to modify commands
        function add_command($command, $description, $sender) {
                $command = "-" . str_replace("-", "_", strtolower($command));
 
-               $this->commands[$command] = array("description" => $description,
-                       "class" => $sender);
+               if ($this->is_system($sender)) {
+                       $this->commands[$command] = array("description" => $description,
+                               "class" => $sender);
+               }
        }
 
        function del_command($command) {
                $command = "-" . strtolower($command);
 
-               unset($this->commands[$command]);
+               if ($this->is_system($sender)) {
+                       unset($this->commands[$command]);
+               }
        }
 
        function lookup_command($command) {
index 447aa8947b37c1724c867a5d35446ce697f4f342..b28bd54912e88011cb8cb39a059ea5e07a1150ca 100644 (file)
@@ -1480,11 +1480,11 @@ class Pref_Feeds extends Handler_Protected {
                print "</div>"; #pane
 
                global $pluginhost;
+
                $pluginhost->run_hooks($pluginhost::HOOK_PREFS_TAB,
                        "hook_prefs_tab", "prefFeeds");
 
                print "</div>"; #container
-
        }
 
        private function feedlist_init_cat($cat_id, $hidden = false) {
index db7a3e04f7d4d03bebb667da714b4cab560ac392..bb1b44ece899795bcb2660f7a3f0f5779eaab80b 100644 (file)
@@ -621,8 +621,133 @@ class Pref_Prefs extends Handler_Protected {
                                <label for='prefs_show_advanced'>" .
                                __("Show additional preferences") . "</label>";
 
+               print "</form>";
                print '</div>'; # inner pane
                print '</div>'; # border container
+
+               print "</div>"; #pane
+
+               print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__('Plugins')."\">";
+
+               print "<h2>".__("Plugins")."</h2>";
+
+               print_notice("You will need to reload Tiny Tiny RSS for plugin changes to take effect.");
+
+               print "<form dojoType=\"dijit.form.Form\" id=\"changePluginsForm\">";
+
+               print "<script type=\"dojo/method\" event=\"onSubmit\" args=\"evt\">
+               evt.preventDefault();
+               if (this.validate()) {
+                       notify_progress('Saving data...', true);
+
+                       new Ajax.Request('backend.php', {
+                               parameters: dojo.objectToQuery(this.getValues()),
+                               onComplete: function(transport) {
+                                       notify('');
+                                       if (confirm(__('Selected plugins have been enabled. Reload?'))) {
+                                               window.location.reload();
+                                       }
+                       } });
+
+               }
+               </script>";
+
+               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pref-prefs\">";
+               print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"setplugins\">";
+
+               print "<table width='100%'>";
+
+               print "<tr><td colspan='4'><h3>".__("System plugins")."</h3></td></tr>";
+
+               print "<tr class=\"title\">
+                               <td width=\"5%\">&nbsp;</td>
+                               <td width='10%'>".__('Plugin')."</td>
+                               <td width=''>".__('Description')."</td>
+                               <td width='5%'>".__('Version')."</td>
+                               <td width='10%'>".__('Author')."</td></tr>";
+
+               $system_enabled = array_map("trim", explode(",", PLUGINS));
+               $user_enabled = array_map("trim", explode(",", get_pref($this->link, "_ENABLED_PLUGINS")));
+
+               $tmppluginhost = new PluginHost($link);
+               $tmppluginhost->load_all();
+
+               foreach ($tmppluginhost->get_plugins() as $name => $plugin) {
+                       $about = $plugin->_about();
+
+                       if ($about[3]) {
+                               if (in_array($name, $system_enabled)) {
+                                       $checked = "checked='1'";
+                               } else {
+                                       $checked = "";
+                               }
+
+                               print "<tr>";
+
+                               print "<td align='center'><input disabled='1'
+                                               dojoType=\"dijit.form.CheckBox\" $checked
+                                               type=\"checkbox\"></td>";
+
+                               print "<td>$name</td>";
+                               print "<td>" . htmlspecialchars($about[1]) . "</td>";
+                               print "<td>" . htmlspecialchars(sprintf("%.2f", $about[0])) . "</td>";
+                               print "<td>" . htmlspecialchars($about[2]) . "</td>";
+
+                               print "</tr>";
+
+                       }
+               }
+
+               print "<tr><td colspan='4'><h3>".__("User plugins")."</h3></td></tr>";
+
+               print "<tr class=\"title\">
+                               <td width=\"5%\">&nbsp;</td>
+                               <td width='10%'>".__('Plugin')."</td>
+                               <td width=''>".__('Description')."</td>
+                               <td width='5%'>".__('Version')."</td>
+                               <td width='10%'>".__('Author')."</td></tr>";
+
+
+               foreach ($tmppluginhost->get_plugins() as $name => $plugin) {
+                       $about = $plugin->_about();
+
+                       if (!$about[3]) {
+
+                               if (in_array($name, $system_enabled)) {
+                                       $checked = "checked='1'";
+                                       $disabled = "disabled='1'";
+                               } else if (in_array($name, $user_enabled)) {
+                                       $checked = "checked='1'";
+                                       $disabled = "";
+                               } else {
+                                       $checked = "";
+                                       $disabled = "";
+                               }
+
+                               print "<tr>";
+
+                               print "<td align='center'><input id='FPCHK-$name' name='plugins[]' value='$name' onclick='toggleSelectRow2(this);'
+                                       dojoType=\"dijit.form.CheckBox\" $checked $disabled
+                                       type=\"checkbox\"></td>";
+
+                               print "<td>$name</td>";
+                               print "<td>" . htmlspecialchars($about[1]) . "</td>";
+                               print "<td>" . htmlspecialchars(sprintf("%.2f", $about[0])) . "</td>";
+                               print "<td>" . htmlspecialchars($about[2]) . "</td>";
+
+                               print "</tr>";
+
+
+
+                       }
+
+               }
+
+               print "</table>";
+
+               print "<p><button dojoType=\"dijit.form.Button\" type=\"submit\">".
+                       __("Enable selected plugins")."</button></p>";
+
                print "</form>";
 
                print "</div>"; #pane
@@ -698,5 +823,11 @@ class Pref_Prefs extends Handler_Protected {
                }
 
        }
+
+       function setplugins() {
+               $plugins = join(",", $_REQUEST["plugins"]);
+
+               set_pref($this->link, "_ENABLED_PLUGINS", $plugins);
+       }
 }
 ?>
index 14b3af517848dc33702fa580345b3cfbadf2ea6d..6848f14b9d90d52636f6e11f691dbd8f7b047eb1 100644 (file)
@@ -1,6 +1,6 @@
 <?php
        define('EXPECTED_CONFIG_VERSION', 26);
-       define('SCHEMA_VERSION', 99);
+       define('SCHEMA_VERSION', 100);
 
        $fetch_last_error = false;
        $pluginhost = false;
                return true;
        }
 
+       function load_user_plugins($link, $owner_uid) {
+               if ($owner_uid) {
+                       $plugins = get_pref($link, "_ENABLED_PLUGINS", $owner_uid);
+
+                       global $pluginhost;
+                       $pluginhost->load($plugins);
+               }
+       }
+
        function login_sequence($link, $login_form = 0) {
                if (SINGLE_USER_MODE) {
-                       return authenticate_user($link, "admin", null);
+                       authenticate_user($link, "admin", null);
+                       load_user_plugins($link, $_SESSION["uid"]);
                } else {
                        if (!$_SESSION["uid"] || !validate_session($link)) {
 
                                setcookie("ttrss_lang", $_SESSION["language"],
                                        time() + SESSION_COOKIE_LIFETIME);
                        }
+
+                       if ($_SESSION["uid"]) {
+                               load_user_plugins($link, $_SESSION["uid"]);
+                       }
                }
        }
 
index d0cbd5b0f9490df16f26dcc6e529c3ded71de3cd..cb906e3c1c4533a835c0698ad2a76879445b6e74 100644 (file)
@@ -7,7 +7,8 @@ class Digest extends Plugin implements IHandler {
        function _about() {
                return array(1.0,
                        "Digest mode for tt-rss (tablet friendly UI)",
-                       "fox");
+                       "fox",
+                       true);
        }
 
        function __construct($host) {
index 42550b1713d0091268f4328d6cd57b34c9b49a44..be6a48551cb650d419774e6c733c9042a7eb46ce 100644 (file)
@@ -9,7 +9,8 @@ class Example extends Plugin {
        function _about() {
                return array(1.0,
                        "Example plugin #1",
-                       "fox");
+                       "fox",
+                       true);
        }
 
        function __construct($host) {
index 205594edd5ce4eada71dfc1f0e49735e861584ec..a0d6d19c740bdbcef0c0912a9770592dd0061a30 100644 (file)
@@ -10,7 +10,8 @@ class Example_Feed extends Plugin {
        function _about() {
                return array(1.0,
                        "Example feed plugin",
-                       "fox");
+                       "fox",
+                       true);
        }
 
        function __construct($host) {
index 024bf5b222e4e35f7c385950dbf96cf8a6fc1767..f15951e088514e2c5f2f7c32ea91a9ac5101b0c3 100644 (file)
@@ -18,7 +18,8 @@ class Example_Routing extends Plugin implements IHandler {
        function _about() {
                return array(1.0,
                        "Example routing plugin",
-                       "fox");
+                       "fox",
+                       true);
        }
 
        function __construct($host) {
index fd80ee44dfefaa3f3cbfc2243be4ee236601abbe..2836bce5a46a6d1c0054445d1d71fc21aecb055e 100644 (file)
@@ -13,7 +13,8 @@ class Instances extends Plugin implements IHandler {
        function _about() {
                return array(1.0,
                        "Support for linking tt-rss instances together and sharing popular feeds.",
-                       "fox");
+                       "fox",
+                       true);
        }
 
        function __construct($host) {
index c85ef32807b792511e5ebac0f55bed875678d011..2148e3c0125064b6a271214ea5025507718349de 100644 (file)
@@ -7,7 +7,8 @@ class Updater extends Plugin {
        function _about() {
                return array(1.0,
                        "Updates tt-rss installation to latest version.",
-                       "fox");
+                       "fox",
+                       true);
        }
 
        function __construct($host) {
index 8b554167371373fde337d2fc2a381906298addf1..e20ac9baa83e2edb7cceb9d5beb56f6df38ccdf2 100644 (file)
--- a/prefs.php
+++ b/prefs.php
@@ -20,7 +20,6 @@
        no_cache_incantation();
 
        header('Content-Type: text/html; charset=utf-8');
-
 ?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
index 2877894260efd9a54e1eb89d43869652be7a7246..bb8bd1028a2fb46580d88f6d48b720a5dea7e244 100644 (file)
@@ -308,7 +308,7 @@ create table ttrss_tags (id integer primary key auto_increment,
 
 create table ttrss_version (schema_version int not null) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
 
-insert into ttrss_version values (99);
+insert into ttrss_version values (100);
 
 create table ttrss_enclosures (id integer primary key auto_increment,
        content_url text not null,
@@ -452,6 +452,8 @@ insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) valu
 
 insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('AUTO_ASSIGN_LABELS', 1, 'true', 'Assign articles to labels automatically', 3);
 
+insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_ENABLED_PLUGINS', 2, '', '', 1);
+
 update ttrss_prefs set access_level = 1 where pref_name in ('ON_CATCHUP_SHOW_NEXT_FEED',
        'SORT_HEADLINES_BY_FEED_DATE',
        'VFEED_GROUP_BY_FEED',
index 432ebf88dc9c0a8a72df86c2ce93559af77133f5..3c508bb3439f0fc5bd30cb6e94d943e081c91ae7 100644 (file)
@@ -256,7 +256,7 @@ create index ttrss_tags_post_int_id_idx on ttrss_tags(post_int_id);
 
 create table ttrss_version (schema_version int not null);
 
-insert into ttrss_version values (99);
+insert into ttrss_version values (100);
 
 create table ttrss_enclosures (id serial not null primary key,
        content_url text not null,
@@ -392,6 +392,8 @@ insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) valu
 
 insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('AUTO_ASSIGN_LABELS', 1, 'true', 'Assign articles to labels automatically', 3);
 
+insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_ENABLED_PLUGINS', 2, '', '', 1);
+
 update ttrss_prefs set access_level = 1 where pref_name in ('ON_CATCHUP_SHOW_NEXT_FEED',
        'SORT_HEADLINES_BY_FEED_DATE',
        'VFEED_GROUP_BY_FEED',
diff --git a/schema/versions/mysql/100.sql b/schema/versions/mysql/100.sql
new file mode 100644 (file)
index 0000000..a360dab
--- /dev/null
@@ -0,0 +1,7 @@
+begin;
+
+insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_ENABLED_PLUGINS', 2, '', '', 1);
+
+update ttrss_version set schema_version = 100;
+
+commit;
diff --git a/schema/versions/pgsql/100.sql b/schema/versions/pgsql/100.sql
new file mode 100644 (file)
index 0000000..a360dab
--- /dev/null
@@ -0,0 +1,7 @@
+begin;
+
+insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_ENABLED_PLUGINS', 2, '', '', 1);
+
+update ttrss_version set schema_version = 100;
+
+commit;