diff --git a/classes/pluginhost.php b/classes/pluginhost.php index d97dfa66660a4f36568885d1295088e179b1d58d..d7db7481cc0cd31ec281be8271a42fcd3d7a731b 100644 --- a/classes/pluginhost.php +++ b/classes/pluginhost.php @@ -5,6 +5,8 @@ class PluginHost { private $plugins = array(); private $handlers = array(); private $commands = array(); + private $storage = array(); + private $owner_uid; const HOOK_ARTICLE_BUTTON = 1; const HOOK_ARTICLE_FILTER = 2; @@ -21,6 +23,10 @@ class PluginHost { function __construct($link) { $this->link = $link; + + $this->storage = $_SESSION["plugin_storage"]; + + if (!$this->storage) $this->storage = array(); } private function register_plugin($name, $plugin) { @@ -70,14 +76,16 @@ class PluginHost { return array(); } } - function load_all($kind) { + function load_all($kind, $owner_uid = false) { $plugins = array_map("basename", glob("plugins/*")); - $this->load(join(",", $plugins), $kind); + $this->load(join(",", $plugins), $kind, $owner_uid); } - 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 +202,89 @@ 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 = false) { + $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]; + } + + 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/feeds.php b/classes/pref/feeds.php index b423eab9525e6fb4aaa3cb9f13aa98ba7f6e0e27..452236a7edf3cba34c1a2a705d9b02a9025d55a8 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 { diff --git a/classes/pref/prefs.php b/classes/pref/prefs.php index 0922e43a8068fcaa86bc6894699684e67ee28453..bb82b355edac60376e5539cbed5d8d9273939ecb 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 "<td>" . htmlspecialchars(sprintf("%.2f", $about[0])) . "</td>"; print "<td>" . htmlspecialchars($about[2]) . "</td>"; + if (count($tmppluginhost->get_all($plugin)) > 0) { + print "<td><a href='#' onclick=\"clearPluginData('$name')\" + class='visibleLink'>".__("Clear data")."</a></td>"; + } + print "</tr>"; } @@ -752,6 +758,10 @@ class Pref_Prefs extends Handler_Protected { print "<td>" . htmlspecialchars(sprintf("%.2f", $about[0])) . "</td>"; print "<td>" . htmlspecialchars($about[2]) . "</td>"; + if (count($tmppluginhost->get_all($plugin)) > 0) { + print "<td><a href='#' onclick=\"clearPluginData('$name')\" class='visibleLink'>".__("Clear data")."</a></td>"; + } + print "</tr>"; @@ -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 f6ef7c2b370ca02ac9cf302f9824d968c36d305c..f0bd31831ab22d76ec18f3b16c133adf0beda350 100644 --- a/include/functions.php +++ b/include/functions.php @@ -1,6 +1,6 @@ <?php define('EXPECTED_CONFIG_VERSION', 26); - define('SCHEMA_VERSION', 100); + define('SCHEMA_VERSION', 101); $fetch_last_error = false; $pluginhost = false; @@ -547,25 +547,6 @@ if (!SINGLE_USER_MODE) { $user_id = false; - /* $modules = explode(",", AUTH_MODULES); - - foreach ($modules as $module) { - $module_class = "auth_$module"; - if (class_exists($module_class)) { - $authenticator = new $module_class($link); - - $user_id = (int) $authenticator->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) { @@ -727,7 +708,11 @@ $plugins = get_pref($link, "_ENABLED_PLUGINS", $owner_uid); global $pluginhost; - $pluginhost->load($plugins, $pluginhost::KIND_USER); + $pluginhost->load($plugins, $pluginhost::KIND_USER, $owner_uid); + + if (get_schema_version($link) > 100) { + $pluginhost->load_data(); + } } } @@ -2590,7 +2575,8 @@ $node = $doc->getElementsByTagName('body')->item(0); - return $doc->saveXML($node); //LIBXML_NOEMPTYTAG + // http://tt-rss.org/redmine/issues/357 + return $doc->saveXML($node, LIBXML_NOEMPTYTAG); } function check_for_update($link) { @@ -4690,17 +4676,6 @@ } -/* function rewrite_urls($line) { - global $url_regex; - - $urls = null; - - $result = preg_replace("/((?<!=.)((http|https|ftp)+):\/\/[^ ,!]+)/i", - "<a target=\"_blank\" href=\"\\1\">\\1</a>", $line); - - return $result; - } */ - function rewrite_urls($html) { libxml_use_internal_errors(true); diff --git a/include/sanity_check.php b/include/sanity_check.php index ee3a0b006540f6d707b76e2e97137036e6e3ae97..2a39cfa42fcf28e5727f6d0db2b8fc83ce8450b1 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."); } diff --git a/js/prefs.js b/js/prefs.js index 0b3f47c0aacfde212fbd7afbcff67bd897c5b955..7ee88ab56a137b11e535c5ccad2ebfd03ea7b2ce 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/plugins/example/example.php b/plugins/example/example.php index eef604b4f599631a3e057a3d9e62be02c642fecc..f3788ae8c6fafec02be2f208d8751f5b349457f0 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 "<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\"> @@ -47,7 +56,7 @@ class Example extends Plugin { notify_info(transport.responseText); } }); - this.reset(); + //this.reset(); } </script>"; @@ -58,7 +67,7 @@ class Example extends Plugin { 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\"></td></tr>"; + print "<td class=\"prefValue\"><input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\" name=\"example_value\" value=\"$value\"></td></tr>"; print "</table>"; diff --git a/schema/ttrss_schema_mysql.sql b/schema/ttrss_schema_mysql.sql index bb8bd1028a2fb46580d88f6d48b720a5dea7e244..d4531308f80c92f2f4bf6757a8f940e081742025 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; @@ -308,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, @@ -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 3c508bb3439f0fc5bd30cb6e94d943e081c91ae7..f52d4191d30fe30384cc65368daf0b156d7a5d62 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 0000000000000000000000000000000000000000..47ff265228b41e6e4085d6fc000204f3bd282355 --- /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 0000000000000000000000000000000000000000..5be859002beec0e6cc0655e8c53ed7ed6454df94 --- /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;