From d8a1d2a25b2247e5a63f5b0ab7f0bd9423a217e5 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Thu, 27 Dec 2012 16:55:25 +0400 Subject: [PATCH 1/9] add experimental key/value storage for plugins --- classes/pluginhost.php | 86 ++++++++++++++++++++++++++++++++++++- include/functions.php | 3 +- plugins/example/example.php | 15 +++++-- 3 files changed, 99 insertions(+), 5 deletions(-) diff --git a/classes/pluginhost.php b/classes/pluginhost.php index d97dfa666..e43b39f9d 100644 --- a/classes/pluginhost.php +++ b/classes/pluginhost.php @@ -1,10 +1,17 @@ link = $link; + + $this->storage = $_SESSION["plugin_storage"]; + + if (!$this->storage) $this->storage = array(); } private function register_plugin($name, $plugin) { @@ -75,9 +86,11 @@ class PluginHost { $this->load(join(",", $plugins), $kind); } - function load($classlist, $kind) { + function load($classlist, $kind, $owner_uid = false) { $plugins = explode(",", $classlist); + $this->owner_uid = (int) $owner_uid; + foreach ($plugins as $class) { $class = trim($class); $class_file = strtolower(basename($class)); @@ -194,5 +207,76 @@ class PluginHost { } } + function load_data($force = false) { + if ($this->owner_uid && (!$_SESSION["plugin_storage"] || $force)) { + $plugin = db_escape_string($plugin); + + $result = db_query($this->link, "SELECT name, content FROM ttrss_plugin_storage + WHERE owner_uid = '".$this->owner_uid."'"); + + while ($line = db_fetch_assoc($result)) { + $this->storage[$line["name"]] = unserialize($line["content"]); + } + + $_SESSION["plugin_storage"] = $this->storage; + } + } + + private function save_data($plugin) { + if ($this->owner_uid) { + $plugin = db_escape_string($plugin); + + db_query($this->link, "BEGIN"); + + $result = db_query($this->link,"SELECT id FROM ttrss_plugin_storage WHERE + owner_uid= '".$this->owner_uid."' AND name = '$plugin'"); + + if (!isset($this->storage[$plugin])) + $this->storage[$plugin] = array(); + + $content = db_escape_string(serialize($this->storage[$plugin])); + + if (db_num_rows($result) != 0) { + db_query($this->link, "UPDATE ttrss_plugin_storage SET content = '$content' + WHERE owner_uid= '".$this->owner_uid."' AND name = '$plugin'"); + + } else { + db_query($this->link, "INSERT INTO ttrss_plugin_storage + (name,owner_uid,content) VALUES + ('$plugin','".$this->owner_uid."','$content')"); + } + + db_query($this->link, "COMMIT"); + } + } + + function set($sender, $name, $value, $sync = true) { + $idx = get_class($sender); + + if (!isset($this->storage[$idx])) + $this->storage[$idx] = array(); + + $this->storage[$idx][$name] = $value; + + $_SESSION["plugin_storage"] = $this->storage; + + if ($sync) $this->save_data(get_class($sender)); + } + + function get($sender, $name, $default_value) { + $idx = get_class($sender); + + if (isset($this->storage[$idx][$name])) { + return $this->storage[$idx][$name]; + } else { + return $default_value; + } + } + + function get_all($sender) { + $idx = get_class($sender); + + return $this->storage[$idx]; + } } ?> diff --git a/include/functions.php b/include/functions.php index f6ef7c2b3..b382b4069 100644 --- a/include/functions.php +++ b/include/functions.php @@ -727,7 +727,8 @@ $plugins = get_pref($link, "_ENABLED_PLUGINS", $owner_uid); global $pluginhost; - $pluginhost->load($plugins, $pluginhost::KIND_USER); + $pluginhost->load($plugins, $pluginhost::KIND_USER, $owner_uid); + $pluginhost->load_data(); } } diff --git a/plugins/example/example.php b/plugins/example/example.php index eef604b4f..f3788ae8c 100644 --- a/plugins/example/example.php +++ b/plugins/example/example.php @@ -23,7 +23,9 @@ class Example extends Plugin { function save() { $example_value = db_escape_string($_POST["example_value"]); - echo "Value set to $example_value (not really)"; + $this->host->set($this, "example", $example_value); + + echo "Value set to $example_value"; } function get_prefs_js() { @@ -35,6 +37,13 @@ class Example extends Plugin { print "
"; + print "
"; + +// print_r($this->host->set($this, "example", rand(0,100))); +// print_r($this->host->get_all($this)); + + $value = $this->host->get($this, "example"); + print "
"; print ""; @@ -58,7 +67,7 @@ class Example extends Plugin { print ""; print ""; - print ""; + print ""; print "
".__("Sample value")."
"; From 5d9abb1e11262b5ef7c6f4695590ce5bdb257b85 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Thu, 27 Dec 2012 19:20:12 +0400 Subject: [PATCH 2/9] add plugin storage table to schema; add ability to clear plugin data --- classes/pluginhost.php | 24 ++++++++++++++++-------- classes/pref/prefs.php | 21 +++++++++++++++++++-- include/functions.php | 21 +-------------------- js/prefs.js | 17 +++++++++++++++++ schema/ttrss_schema_mysql.sql | 9 +++++++++ schema/ttrss_schema_pgsql.sql | 9 ++++++++- schema/versions/mysql/101.sql | 12 ++++++++++++ schema/versions/pgsql/101.sql | 11 +++++++++++ 8 files changed, 93 insertions(+), 31 deletions(-) create mode 100644 schema/versions/mysql/101.sql create mode 100644 schema/versions/pgsql/101.sql diff --git a/classes/pluginhost.php b/classes/pluginhost.php index e43b39f9d..d7db7481c 100644 --- a/classes/pluginhost.php +++ b/classes/pluginhost.php @@ -1,9 +1,4 @@ load(join(",", $plugins), $kind); + $this->load(join(",", $plugins), $kind, $owner_uid); } function load($classlist, $kind, $owner_uid = false) { @@ -263,7 +258,7 @@ class PluginHost { if ($sync) $this->save_data(get_class($sender)); } - function get($sender, $name, $default_value) { + function get($sender, $name, $default_value = false) { $idx = get_class($sender); if (isset($this->storage[$idx][$name])) { @@ -278,5 +273,18 @@ class PluginHost { return $this->storage[$idx]; } + + function clear_data($sender) { + if ($this->owner_uid) { + $idx = get_class($sender); + + unset($this->storage[$idx]); + + db_query($this->link, "DELETE FROM ttrss_plugin_storage WHERE name = '$idx' + AND owner_uid = " . $this->owner_uid); + + $_SESSION["plugin_storage"] = $this->storage; + } + } } ?> diff --git a/classes/pref/prefs.php b/classes/pref/prefs.php index 0922e43a8..bb82b355e 100644 --- a/classes/pref/prefs.php +++ b/classes/pref/prefs.php @@ -683,8 +683,9 @@ class Pref_Prefs extends Handler_Protected { $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($tmppluginhost::KIND_ALL); + $tmppluginhost = new PluginHost($this->link); + $tmppluginhost->load_all($tmppluginhost::KIND_ALL, $_SESSION["uid"]); + $tmppluginhost->load_data(true); foreach ($tmppluginhost->get_plugins() as $name => $plugin) { $about = $plugin->about(); @@ -707,6 +708,11 @@ class Pref_Prefs extends Handler_Protected { print "" . htmlspecialchars(sprintf("%.2f", $about[0])) . ""; print "" . htmlspecialchars($about[2]) . ""; + if (count($tmppluginhost->get_all($plugin)) > 0) { + print "".__("Clear data").""; + } + print ""; } @@ -752,6 +758,10 @@ class Pref_Prefs extends Handler_Protected { print "" . htmlspecialchars(sprintf("%.2f", $about[0])) . ""; print "" . htmlspecialchars($about[2]) . ""; + if (count($tmppluginhost->get_all($plugin)) > 0) { + print "".__("Clear data").""; + } + print ""; @@ -846,5 +856,12 @@ class Pref_Prefs extends Handler_Protected { set_pref($this->link, "_ENABLED_PLUGINS", $plugins); } + + function clearplugindata() { + $name = db_escape_string($_REQUEST["name"]); + + global $pluginhost; + $pluginhost->clear_data($pluginhost->get_plugin($name)); + } } ?> diff --git a/include/functions.php b/include/functions.php index b382b4069..89e767e2c 100644 --- a/include/functions.php +++ b/include/functions.php @@ -1,6 +1,6 @@ authenticate($login, $password); - - if ($user_id) { - $_SESSION["auth_module"] = $module; - break; - } - - } else { - print T_sprintf("Fatal: authentication module %s not found.", $module); - die; - } - } */ global $pluginhost; foreach ($pluginhost->get_hooks($pluginhost::HOOK_AUTH_USER) as $plugin) { diff --git a/js/prefs.js b/js/prefs.js index 0b3f47c0a..7ee88ab56 100644 --- a/js/prefs.js +++ b/js/prefs.js @@ -1925,3 +1925,20 @@ function toggleAdvancedPrefs() { exception_error("toggleAdvancedPrefs", e); } } + +function clearPluginData(name) { + try { + if (confirm(__("Clear stored data for this plugin?"))) { + notify_progress("Loading, please wait..."); + + new Ajax.Request("backend.php", { + parameters: "?op=pref-prefs&method=clearplugindata&name=" + param_escape(name), + onComplete: function(transport) { + notify(''); + updatePrefsList(); + } }); + } + } catch (e) { + exception_error("clearPluginData", e); + } +} diff --git a/schema/ttrss_schema_mysql.sql b/schema/ttrss_schema_mysql.sql index bb8bd1028..0b0c587b9 100644 --- a/schema/ttrss_schema_mysql.sql +++ b/schema/ttrss_schema_mysql.sql @@ -1,6 +1,7 @@ SET NAMES utf8; SET CHARACTER SET utf8; +drop table if exists ttrss_plugin_storage; drop table if exists ttrss_linked_feeds; drop table if exists ttrss_linked_instances; drop table if exists ttrss_access_keys; @@ -528,4 +529,12 @@ create table ttrss_linked_feeds ( subscribers integer not null, foreign key (instance_id) references ttrss_linked_instances(id) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=UTF8; +create table ttrss_plugin_storage ( + id integer not null auto_increment primary key, + name varchar(100) not null, + owner_uid integer not null, + content longtext not null, + foreign key (owner_uid) references ttrss_users(id) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=UTF8; + + commit; diff --git a/schema/ttrss_schema_pgsql.sql b/schema/ttrss_schema_pgsql.sql index 3c508bb34..f52d4191d 100644 --- a/schema/ttrss_schema_pgsql.sql +++ b/schema/ttrss_schema_pgsql.sql @@ -1,3 +1,4 @@ +drop table if exists ttrss_plugin_storage; drop table if exists ttrss_linked_feeds; drop table if exists ttrss_linked_instances; drop table if exists ttrss_access_keys; @@ -256,7 +257,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 (100); +insert into ttrss_version values (101); create table ttrss_enclosures (id serial not null primary key, content_url text not null, @@ -461,4 +462,10 @@ create table ttrss_linked_feeds ( instance_id integer not null references ttrss_linked_instances(id) ON DELETE CASCADE, subscribers integer not null); +create table ttrss_plugin_storage ( + id serial not null primary key, + name varchar(100) not null, + owner_uid integer not null references ttrss_users(id) ON DELETE CASCADE, + content text not null); + commit; diff --git a/schema/versions/mysql/101.sql b/schema/versions/mysql/101.sql new file mode 100644 index 000000000..47ff26522 --- /dev/null +++ b/schema/versions/mysql/101.sql @@ -0,0 +1,12 @@ +begin; + +create table ttrss_plugin_storage ( + id integer not null auto_increment primary key, + name varchar(100) not null, + owner_uid integer not null, + content longtext not null, + foreign key (owner_uid) references ttrss_users(id) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=UTF8; + +update ttrss_version set schema_version = 101; + +commit; diff --git a/schema/versions/pgsql/101.sql b/schema/versions/pgsql/101.sql new file mode 100644 index 000000000..5be859002 --- /dev/null +++ b/schema/versions/pgsql/101.sql @@ -0,0 +1,11 @@ +begin; + +create table ttrss_plugin_storage ( + id serial not null primary key, + name varchar(100) not null, + owner_uid integer not null references ttrss_users(id) ON DELETE CASCADE, + content text not null); + +update ttrss_version set schema_version = 101; + +commit; From ec6732f460cb471cbce13938c5aff75f5ff34e2c Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Thu, 27 Dec 2012 19:35:42 +0400 Subject: [PATCH 3/9] Revert "sanitize: do not use LIBXML_NOEMPTYTAG (refs #522)" This reverts commit b0ec17ea3cd155475dfaa2c40f46aacbd94654be. --- include/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/functions.php b/include/functions.php index 89e767e2c..9994240c6 100644 --- a/include/functions.php +++ b/include/functions.php @@ -2572,7 +2572,7 @@ $node = $doc->getElementsByTagName('body')->item(0); - return $doc->saveXML($node); //LIBXML_NOEMPTYTAG + return $doc->saveXML($node, LIBXML_NOEMPTYTAG); } function check_for_update($link) { From 2a3b7f25fcc99bc53d7c0f93c4e44ce2804bcc04 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Thu, 27 Dec 2012 19:36:22 +0400 Subject: [PATCH 4/9] sanitize: mention why LIBXML_NOEMPTYTAG is used --- include/functions.php | 1 + 1 file changed, 1 insertion(+) diff --git a/include/functions.php b/include/functions.php index 9994240c6..540ab4d4a 100644 --- a/include/functions.php +++ b/include/functions.php @@ -4723,6 +4723,7 @@ $node = $doc->getElementsByTagName('body')->item(0); // http://tt-rss.org/forum/viewtopic.php?f=1&t=970 + // http://tt-rss.org/redmine/issues/357 if ($node) return $doc->saveXML($node, LIBXML_NOEMPTYTAG); else From d26111f541d196944ab8bf630f2fda3ec6aae9d0 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Thu, 27 Dec 2012 20:27:28 +0400 Subject: [PATCH 5/9] mysql: fix schema version --- schema/ttrss_schema_mysql.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema/ttrss_schema_mysql.sql b/schema/ttrss_schema_mysql.sql index 0b0c587b9..d4531308f 100644 --- a/schema/ttrss_schema_mysql.sql +++ b/schema/ttrss_schema_mysql.sql @@ -309,7 +309,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 (100); +insert into ttrss_version values (101); create table ttrss_enclosures (id integer primary key auto_increment, content_url text not null, From e9c04fd4e33e4b4da7109b4a4241629416ecd336 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Thu, 27 Dec 2012 20:28:06 +0400 Subject: [PATCH 6/9] load_user_plugins: only load data when schema version > 100 --- include/functions.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/functions.php b/include/functions.php index 540ab4d4a..6dc494454 100644 --- a/include/functions.php +++ b/include/functions.php @@ -709,7 +709,10 @@ global $pluginhost; $pluginhost->load($plugins, $pluginhost::KIND_USER, $owner_uid); - $pluginhost->load_data(); + + if (get_schema_version($link) > 100) { + $pluginhost->load_data(); + } } } From c5bb0440d36a41df615ac03e2d05ef9b8638f280 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Thu, 27 Dec 2012 20:35:13 +0400 Subject: [PATCH 7/9] place the #357 comment to the correct instance of saveXML(), cleanup old version of rewrite_urls() --- include/functions.php | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/include/functions.php b/include/functions.php index 6dc494454..f0bd31831 100644 --- a/include/functions.php +++ b/include/functions.php @@ -2575,6 +2575,7 @@ $node = $doc->getElementsByTagName('body')->item(0); + // http://tt-rss.org/redmine/issues/357 return $doc->saveXML($node, LIBXML_NOEMPTYTAG); } @@ -4675,17 +4676,6 @@ } -/* function rewrite_urls($line) { - global $url_regex; - - $urls = null; - - $result = preg_replace("/((?\\1", $line); - - return $result; - } */ - function rewrite_urls($html) { libxml_use_internal_errors(true); @@ -4726,7 +4716,6 @@ $node = $doc->getElementsByTagName('body')->item(0); // http://tt-rss.org/forum/viewtopic.php?f=1&t=970 - // http://tt-rss.org/redmine/issues/357 if ($node) return $doc->saveXML($node, LIBXML_NOEMPTYTAG); else From 72679db8c7e76e037239de9c820828ed9ec3dac1 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Thu, 27 Dec 2012 21:22:39 +0400 Subject: [PATCH 8/9] add sanity check for no auth modules being enabled in PLUGINS --- include/sanity_check.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/sanity_check.php b/include/sanity_check.php index ee3a0b006..2a39cfa42 100644 --- a/include/sanity_check.php +++ b/include/sanity_check.php @@ -12,6 +12,10 @@ require_once "sanity_config.php"; + if (strpos(PLUGINS, "auth_") === FALSE) { + array_push($errors, "Please enable at least one authentication module via PLUGINS constant in config.php"); + } + if (function_exists('posix_getuid') && posix_getuid() == 0) { array_push($errors, "Please don't run this script as root."); } From 715a8239ac5cb67b49a2a66984303f27f11db2b3 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Thu, 27 Dec 2012 21:50:56 +0400 Subject: [PATCH 9/9] fix feedEditor not saving --- classes/pref/feeds.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/pref/feeds.php b/classes/pref/feeds.php index b423eab95..452236a7e 100644 --- a/classes/pref/feeds.php +++ b/classes/pref/feeds.php @@ -949,7 +949,7 @@ class Pref_Feeds extends Handler_Protected { include_in_digest = $include_in_digest, always_display_enclosures = $always_display_enclosures, mark_unread_on_update = $mark_unread_on_update, - update_on_checksum_change = $update_on_checksum_change, + update_on_checksum_change = $update_on_checksum_change WHERE id = '$feed_id' AND owner_uid = " . $_SESSION["uid"]); } else {