experimental support for per-user plugins (bump schema)
This commit is contained in:
parent
57e9729425
commit
de612e7a38
|
@ -63,6 +63,10 @@
|
||||||
authenticate_user($link, "admin", null);
|
authenticate_user($link, "admin", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($_SESSION["uid"]) {
|
||||||
|
load_user_plugins($link, $_SESSION["uid"]);
|
||||||
|
}
|
||||||
|
|
||||||
$purge_intervals = array(
|
$purge_intervals = array(
|
||||||
0 => __("Use default"),
|
0 => __("Use default"),
|
||||||
-1 => __("Never purge"),
|
-1 => __("Never purge"),
|
||||||
|
|
|
@ -78,32 +78,45 @@ class PluginHost {
|
||||||
$class_file = strtolower(basename($class));
|
$class_file = strtolower(basename($class));
|
||||||
$file = dirname(__FILE__)."/../plugins/$class_file/$class_file.php";
|
$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")) {
|
if (class_exists($class) && is_subclass_of($class, "Plugin")) {
|
||||||
$plugin = new $class($this);
|
$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) {
|
function add_handler($handler, $method, $sender) {
|
||||||
$handler = str_replace("-", "_", strtolower($handler));
|
$handler = str_replace("-", "_", strtolower($handler));
|
||||||
$method = strtolower($method);
|
$method = strtolower($method);
|
||||||
|
|
||||||
if (!is_array($this->handlers[$handler])) {
|
if ($this->is_system($sender)) {
|
||||||
$this->handlers[$handler] = array();
|
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) {
|
function del_handler($handler, $method) {
|
||||||
$handler = str_replace("-", "_", strtolower($handler));
|
$handler = str_replace("-", "_", strtolower($handler));
|
||||||
$method = strtolower($method);
|
$method = strtolower($method);
|
||||||
|
|
||||||
unset($this->handlers[$handler][$method]);
|
if ($this->is_system($sender)) {
|
||||||
|
unset($this->handlers[$handler][$method]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function lookup_handler($handler, $method) {
|
function lookup_handler($handler, $method) {
|
||||||
|
@ -121,17 +134,22 @@ class PluginHost {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// only system plugins are allowed to modify commands
|
||||||
function add_command($command, $description, $sender) {
|
function add_command($command, $description, $sender) {
|
||||||
$command = "-" . str_replace("-", "_", strtolower($command));
|
$command = "-" . str_replace("-", "_", strtolower($command));
|
||||||
|
|
||||||
$this->commands[$command] = array("description" => $description,
|
if ($this->is_system($sender)) {
|
||||||
"class" => $sender);
|
$this->commands[$command] = array("description" => $description,
|
||||||
|
"class" => $sender);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function del_command($command) {
|
function del_command($command) {
|
||||||
$command = "-" . strtolower($command);
|
$command = "-" . strtolower($command);
|
||||||
|
|
||||||
unset($this->commands[$command]);
|
if ($this->is_system($sender)) {
|
||||||
|
unset($this->commands[$command]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function lookup_command($command) {
|
function lookup_command($command) {
|
||||||
|
|
|
@ -1480,11 +1480,11 @@ class Pref_Feeds extends Handler_Protected {
|
||||||
print "</div>"; #pane
|
print "</div>"; #pane
|
||||||
|
|
||||||
global $pluginhost;
|
global $pluginhost;
|
||||||
|
|
||||||
$pluginhost->run_hooks($pluginhost::HOOK_PREFS_TAB,
|
$pluginhost->run_hooks($pluginhost::HOOK_PREFS_TAB,
|
||||||
"hook_prefs_tab", "prefFeeds");
|
"hook_prefs_tab", "prefFeeds");
|
||||||
|
|
||||||
print "</div>"; #container
|
print "</div>"; #container
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function feedlist_init_cat($cat_id, $hidden = false) {
|
private function feedlist_init_cat($cat_id, $hidden = false) {
|
||||||
|
|
|
@ -621,8 +621,133 @@ class Pref_Prefs extends Handler_Protected {
|
||||||
<label for='prefs_show_advanced'>" .
|
<label for='prefs_show_advanced'>" .
|
||||||
__("Show additional preferences") . "</label>";
|
__("Show additional preferences") . "</label>";
|
||||||
|
|
||||||
|
print "</form>";
|
||||||
print '</div>'; # inner pane
|
print '</div>'; # inner pane
|
||||||
print '</div>'; # border container
|
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%\"> </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%\"> </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 "</form>";
|
||||||
|
|
||||||
print "</div>"; #pane
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
define('EXPECTED_CONFIG_VERSION', 26);
|
define('EXPECTED_CONFIG_VERSION', 26);
|
||||||
define('SCHEMA_VERSION', 99);
|
define('SCHEMA_VERSION', 100);
|
||||||
|
|
||||||
$fetch_last_error = false;
|
$fetch_last_error = false;
|
||||||
$pluginhost = false;
|
$pluginhost = false;
|
||||||
|
@ -711,9 +711,19 @@
|
||||||
return true;
|
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) {
|
function login_sequence($link, $login_form = 0) {
|
||||||
if (SINGLE_USER_MODE) {
|
if (SINGLE_USER_MODE) {
|
||||||
return authenticate_user($link, "admin", null);
|
authenticate_user($link, "admin", null);
|
||||||
|
load_user_plugins($link, $_SESSION["uid"]);
|
||||||
} else {
|
} else {
|
||||||
if (!$_SESSION["uid"] || !validate_session($link)) {
|
if (!$_SESSION["uid"] || !validate_session($link)) {
|
||||||
|
|
||||||
|
@ -735,6 +745,10 @@
|
||||||
setcookie("ttrss_lang", $_SESSION["language"],
|
setcookie("ttrss_lang", $_SESSION["language"],
|
||||||
time() + SESSION_COOKIE_LIFETIME);
|
time() + SESSION_COOKIE_LIFETIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($_SESSION["uid"]) {
|
||||||
|
load_user_plugins($link, $_SESSION["uid"]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,8 @@ class Digest extends Plugin implements IHandler {
|
||||||
function _about() {
|
function _about() {
|
||||||
return array(1.0,
|
return array(1.0,
|
||||||
"Digest mode for tt-rss (tablet friendly UI)",
|
"Digest mode for tt-rss (tablet friendly UI)",
|
||||||
"fox");
|
"fox",
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function __construct($host) {
|
function __construct($host) {
|
||||||
|
|
|
@ -9,7 +9,8 @@ class Example extends Plugin {
|
||||||
function _about() {
|
function _about() {
|
||||||
return array(1.0,
|
return array(1.0,
|
||||||
"Example plugin #1",
|
"Example plugin #1",
|
||||||
"fox");
|
"fox",
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function __construct($host) {
|
function __construct($host) {
|
||||||
|
|
|
@ -10,7 +10,8 @@ class Example_Feed extends Plugin {
|
||||||
function _about() {
|
function _about() {
|
||||||
return array(1.0,
|
return array(1.0,
|
||||||
"Example feed plugin",
|
"Example feed plugin",
|
||||||
"fox");
|
"fox",
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function __construct($host) {
|
function __construct($host) {
|
||||||
|
|
|
@ -18,7 +18,8 @@ class Example_Routing extends Plugin implements IHandler {
|
||||||
function _about() {
|
function _about() {
|
||||||
return array(1.0,
|
return array(1.0,
|
||||||
"Example routing plugin",
|
"Example routing plugin",
|
||||||
"fox");
|
"fox",
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function __construct($host) {
|
function __construct($host) {
|
||||||
|
|
|
@ -13,7 +13,8 @@ class Instances extends Plugin implements IHandler {
|
||||||
function _about() {
|
function _about() {
|
||||||
return array(1.0,
|
return array(1.0,
|
||||||
"Support for linking tt-rss instances together and sharing popular feeds.",
|
"Support for linking tt-rss instances together and sharing popular feeds.",
|
||||||
"fox");
|
"fox",
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function __construct($host) {
|
function __construct($host) {
|
||||||
|
|
|
@ -7,7 +7,8 @@ class Updater extends Plugin {
|
||||||
function _about() {
|
function _about() {
|
||||||
return array(1.0,
|
return array(1.0,
|
||||||
"Updates tt-rss installation to latest version.",
|
"Updates tt-rss installation to latest version.",
|
||||||
"fox");
|
"fox",
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function __construct($host) {
|
function __construct($host) {
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
no_cache_incantation();
|
no_cache_incantation();
|
||||||
|
|
||||||
header('Content-Type: text/html; charset=utf-8');
|
header('Content-Type: text/html; charset=utf-8');
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
|
|
@ -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;
|
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,
|
create table ttrss_enclosures (id integer primary key auto_increment,
|
||||||
content_url text not null,
|
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('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',
|
update ttrss_prefs set access_level = 1 where pref_name in ('ON_CATCHUP_SHOW_NEXT_FEED',
|
||||||
'SORT_HEADLINES_BY_FEED_DATE',
|
'SORT_HEADLINES_BY_FEED_DATE',
|
||||||
'VFEED_GROUP_BY_FEED',
|
'VFEED_GROUP_BY_FEED',
|
||||||
|
|
|
@ -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);
|
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,
|
create table ttrss_enclosures (id serial not null primary key,
|
||||||
content_url text not null,
|
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('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',
|
update ttrss_prefs set access_level = 1 where pref_name in ('ON_CATCHUP_SHOW_NEXT_FEED',
|
||||||
'SORT_HEADLINES_BY_FEED_DATE',
|
'SORT_HEADLINES_BY_FEED_DATE',
|
||||||
'VFEED_GROUP_BY_FEED',
|
'VFEED_GROUP_BY_FEED',
|
||||||
|
|
|
@ -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;
|
|
@ -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;
|
Loading…
Reference in New Issue